从归并排序到逆序对数目计算。
2017-05-04 11:27
337 查看
归并排序中“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。
归并过程参考下图:
2-路归并排序算法是基于分治的思想,先将含有n个元素的待排序表分成各n/2个元素的子表,对这个两个子表进行排序,这个是mergeSort()操作;再将排好序的两个子表合并成一个表,这个是merge()操作。
空间效率:merge()操作中,辅助空间占用n个单元,故其空间复杂度为O(n);
时间效率:每一趟归并的时间复杂度为O(n),共需进行log2(n)(向上取整)趟归并,所以算法时间复杂度为O(nlog2n)。
稳定性:merge操作不会改变相同关键字记录的相对次序,所以归并算法是一个稳定的排序算法。
2-路归并趟数计算:
第1趟结束后,归并段长度为2;
第2趟结束后,归并段长度为4;
第m趟结束后,归并段长度为2^m=n;
所以需要的趟数为:m=log2(n)(向上取整)。
k-路归并趟数计算:
第1趟结束后,归并段长度为k;
第2趟结束后,归并段长度为k^2;
第m趟结束后,归并段长度为k^m=n;
所以需要的趟数为:logk(n)(向上取整)。
逆序对数目计算:
观察归并排序——合并数列(1,3,5)与(2,4)的时候:
1.先取出前面数列中的1。
2.然后取出后面数列中的2,明显!这个2和前面的3,5都可以组成逆序数对即3和2,5和2都是逆序数对。
3.然后取出前面数列中的3。
4.然后取出后面数列中的4,同理,可知这个4和前面数列中的5可以组成一个逆序数对。
注意,只有在取到后面数列的时候才计算逆序对数目。归并排序的时间复杂度是O(N * LogN),因此这种从归并排序到数列的逆序数对的解法的时间复杂度同样是O(N * LogN).
2-路归并排序以及逆序对数的计算Java代码如下:
参考:http://blog.csdn.net/morewindows/article/details/8029996
归并过程参考下图:
2-路归并排序算法是基于分治的思想,先将含有n个元素的待排序表分成各n/2个元素的子表,对这个两个子表进行排序,这个是mergeSort()操作;再将排好序的两个子表合并成一个表,这个是merge()操作。
空间效率:merge()操作中,辅助空间占用n个单元,故其空间复杂度为O(n);
时间效率:每一趟归并的时间复杂度为O(n),共需进行log2(n)(向上取整)趟归并,所以算法时间复杂度为O(nlog2n)。
稳定性:merge操作不会改变相同关键字记录的相对次序,所以归并算法是一个稳定的排序算法。
2-路归并趟数计算:
第1趟结束后,归并段长度为2;
第2趟结束后,归并段长度为4;
第m趟结束后,归并段长度为2^m=n;
所以需要的趟数为:m=log2(n)(向上取整)。
k-路归并趟数计算:
第1趟结束后,归并段长度为k;
第2趟结束后,归并段长度为k^2;
第m趟结束后,归并段长度为k^m=n;
所以需要的趟数为:logk(n)(向上取整)。
逆序对数目计算:
观察归并排序——合并数列(1,3,5)与(2,4)的时候:
1.先取出前面数列中的1。
2.然后取出后面数列中的2,明显!这个2和前面的3,5都可以组成逆序数对即3和2,5和2都是逆序数对。
3.然后取出前面数列中的3。
4.然后取出后面数列中的4,同理,可知这个4和前面数列中的5可以组成一个逆序数对。
注意,只有在取到后面数列的时候才计算逆序对数目。归并排序的时间复杂度是O(N * LogN),因此这种从归并排序到数列的逆序数对的解法的时间复杂度同样是O(N * LogN).
2-路归并排序以及逆序对数的计算Java代码如下:
// 归并排序的代码实现 public class MergeSort { int count = 0; // 这个成员变量中会存放逆序数对的个数。 // 传入数组和其最大最小索引值。 public void mergeSort(int [] data,int low,int high){ if(low < high){ // 递归结束条件,当数组只有一个值时,不再进行。 int mid = (low+high)/2; mergeSort(data,low,mid); mergeSort(data,mid+1,high); merge(data,low,mid,high); } } // merge()的功能是将前后相邻的两个有序表归并成一个有序表。 private void merge(int[] data, int low, int mid, int high) { // TODO Auto-generated method stub int [] temp = new int[high-low+1]; int i=0,j=0,k=0; for(i = low,j = mid+1,k=0;i <= mid && j <= high;k++ ){ if(data[i] <= data[j]){ temp[k] = data[i++]; }else{ count += mid-i+1; // 计算逆序数对只需要在归并排序的基础上添加这一行代码即可。 temp[k] = data[j++]; } } while(i <= mid) temp[k++] = data[i++]; while(j <= high) temp[k++] = data[j++]; i = 0; j = low; while(i < temp.length) data[j++] = temp[i++]; } }
参考:http://blog.csdn.net/morewindows/article/details/8029996
相关文章推荐
- 归并排序计算逆序对数目
- 归并排序应用——数组中的逆序对 and 计算数组的小和
- (应用排序算法编程7.2.2)POJ 2299 Ultra-QuickSort(使用归并排序来计算逆序对的个数)
- 归并排序求逆序对数目
- hash一下 + 归并排序计算逆序对数
- 使用归并排序计算逆序对个数
- 如何运用归并排序快速求得逆序对数目
- 【SGU 180】Inversions —— 归并排序或树形数组计算逆序对
- 百练+归并排序求逆序数+注意最后是按逆序数大小输出原来的序列啊!
- Giraph源码分析(八)—— 统计每个SuperStep中参与计算的顶点数目
- codeforces 414C C. Mashmokh and Reverse Operation(归并排序求逆序对)
- poj 2299 Ultra-QuickSort【归并排序求逆序数】
- 归并排序-逆序对的求解
- 归并排序以及逆序对统计
- 分割RGB中物体并计算数目
- 递增子序列数目计算的算法
- 归并排序求逆序
- 归并排序求逆序对数
- 计算由N个五角形组成的圈的生成树的数目
- 【算法】逆序对问题的四种解法(归并排序,BST,树状数组,线段树)及变形