[转]http://blog.csdn.net/lewutian/article/details/4549656
并归排序法求逆序数 收藏
逆序对(inversion pair)是指在序列{a0,a1,a2...an}中,若ai<aj(i>j),则(ai,aj)上一对逆序对。而逆序数 (inversion number)顾名思义就是序列中逆序对的个数。例如: 1 2 3是顺序,则逆序数是0;1 3 2中(2,3)满足逆序对的条件,所以逆序数只有1; 3 2 1中(1,2)(1,3)(2,3)满足逆序对,所以逆序是3。由定义不能想象,序列n的逆序数范围在[0,n*(n-1)/2],其中顺序时逆序数为 0,完全逆序时逆序数是n*(n-1)/2。
就我所知,目前求这种逆序对最快的算法是利用归并排序,其时间复杂度为O(nlgn), 空间复杂度为O(n)
闲话少说,看代码
#include <stdio.h>
#include <stdlib.h>
/**///////////////////////////////////////////////////////////////////////////
//求逆序数
//最快的算法是归并排序时计算逆序个数,时间复杂度是nlog2n, 空间复杂度是2n
//a为字符数组,len为字符数组的长度
int number = 0; //number表示逆序对的个数
void mergePass(char *, char *, int, int);
void merge(char*, char*, int, int, int);
void copy(char *dest, char *src, int l, int r)
{
while(l <= r)
{
dest[l] = src[l];
l++;
}
}
void mergeSort(char *a, int size)
{
char *b = (char*)malloc(sizeof(char) * size);
mergePass(a, b, 0, size - 1);
free(b);
}
void mergePass(char *a, char *b, int l, int r)
{
int m;
if(l < r)
{
m = (l + r) / 2;
mergePass(a,b,l,m);
mergePass(a,b,m+1,r);
merge(a,b,l,m,r);
copy(a,b,l,r);
}
}
void merge(char *a, char *b, int l, int m, int r)
{
int i = l, j = m + 1;
while( i <= m && j <= r)
{
if(a[i] <= a[j])
b[l++] = a[i++];
else
{
b[l++] = a[j++];
//a[i] > a[j], 表示出现了逆序对,此时由于
//a[i..m]是已经有序了,那么a[i+1], a[i+2], ... a[m]都是大于a[j]的,
//都可以和a[j]组成逆序对,因此number += m - i + 1
number += m-i+1;
}
}
while(i <= m)
b[l++] = a[i++];
while(j <= r)
b[l++] = a[j++];
}
int main()
{
char a[10] = {'A','A','C','A','T','G','A','A','G','G'};
char b[5] = {'A', 'B', 'A', 'A','A'};
mergeSort(a, 10);
for(int i = 0; i < 10; i++)
printf("%c ",a[i]);
printf("%d ", number);
system("pause");
return 0;
}
分享到:
相关推荐
利用二路归并排序求逆序对,很巧妙的一种算法
该资源包含连个用java实现的程序源码,一个是字符串逆序算程序,一个是排序程序,都是计算机数据结构中的常见问题实现。
编写程序,实现所有内部排序算法,并比较这些算法在不同数据量下的运行时间。 (1)排序算法包括:插入排序、希尔排序、堆排序、归并排序、快速排序、基数排序。 (2)对整数进行排序。 (3)程序功能:可从键盘输入...
针对方程式重排序等算法存在的程序运行速度、信息隐藏量等问题,提出基于方程式操作数系数排列逆序数的软件水印算法。重新排列那些可以相互交换的操作数,使各操作数的系数按照一定次序排列。通过排列的逆序数和二...
通过归并排序计算逆序数,算法高效,是很多需要运用到逆序数问题的很好的一个接口
实现以下常用的内部排序算法并进行性能比较:"直接插入排序"," 折半插入排序"," 2—路插入排序"," 表插入排序"," 希尔排序"," 起泡排序"," 快速排序"," 简单选择排序"," 树形选择排序"," 堆排序"," 归并排序"," 链式...
题目一: 内排序算法比较 1) 对以下6种常用的内部排序算法进行比较:起泡排序,直接插入排序,简单选择排序,快速排序,希尔排序,堆排序。 2) 待排序记录的文件个数不小于1000( 其数据用伪随机数产生),至少用5组...
严蔚敏教材中所讲的将递增的两个顺序表按逆序合并算法的实现。不错的算法,很容易理解。代码可以直接运行
请采用类似“合并排序算法”的分治思路以O(nlogn)的效率来实现逆序对的统计。 一个n个元素序列的逆序对个数由三部分构成: (1)它的左半部分逆序对的个数,(2)加上右半部分逆序对的个数,(3)再加上左半部分...
逆序对,时间复杂度nlogn,采用修改后的合并排序算法
使用简单数组实现下面各种排序算法的功能,并进行比较, 排序算法如下: a) 插入排序; b) 希尔排序; c) 冒泡排序; d) 快速排序; e) 简单选择排序; f) 堆排序; g) 归并排序; h) 基数排序(选作); i) 其他; ...
我用vs2017写的包含八大排序算法和随机生成数的算法。其中包括:冒泡排序,快速排序,选择排序,插入排序,桶排序,希尔排序,计数排序。其实只有七个排序算法。
排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序.mht
1、本演示程序对以下6种常用的内部排序算法进行实测比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。 2、待排序表的表的元素的关键字为整数,表长不小于100;其中的数据要用伪随机数产生...
1) 对以下 6 种常用的内部排序算法进行比较:起泡排序,直接插入排序,简单选择排 序,快速排序,希尔排序,堆排序。 2) 待排序记录的文件个数不小于 1000( 其数据用伪随机数产生 ),至少用5 组不同的 输入数据作...
1) 问题描述 对各种排序方法(直接插入排序、希尔排序、起泡排序、快速排序、...(2) 产生正序和逆序的初始排列分别调用上述排序算法,并比较时间性能; (3) 产生随机的初始排列分别调用上述排序算法,并比较时间性能。
插入排序、选择排序、冒泡排序、归并排序、快速排序和堆排序。 有详细的思路及算法分析、伪代码、图解、示例代码等。 比较列表中的相邻元素,如果它们是逆序的话就交换它们的位置。重复多次后,最大的元素就“沉到”...
1、通过修改程序,实现程序在要求的数据量下求出以下六种内部排序算法的移动次数和比较次数:直接插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序。 2、输入的数据量分别按照正序、逆序、随机顺序的不同...
内部排序算法比较 【问题描述】 在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。 ...
教材中,每种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。 基本要求: (1)对以下6种常用的内部...