概述
-
归并排序,顾名思义:递归+合并
合并:是将两个数列合并,如1 6 4 和 2 5 3合并,为了方便,我们将其命名为数列1和数列2,合并数列1和数列2,
从两者的最左边的位置开始比较,
1 < 2 ,将1放入数列3 中备用,数列1 的指针后移。
6 > 2 ,将2放入数列3中备用, 数列2的指针后移。
6 > 5 ,将5放入数列3中备用,数列2的指针后移。
6 > 3 ,将3放入数列3中备用,数列2的指针后移。
这时,数列2已经遍历完了。
直接将数列1中的所剩元素都放入数列3中。
得到数列3: 1 2 5 3 6 4 合并过程通过模拟可以容易的写出代码:
void mergeArray(int l, int mid, int r){
int l1 = l, r1 = mid;
int l2 = mid+1, r2 = r;
int k = l1;
while(l1 <= r1 && l2 <= r2){
if(a[l1] < a[l2]){
ans[k++] = a[l1++];
}else{
ans[k++] = a[l2++];
}
}
while(l1 <= r1) ans[k++] = a[l1++];
while(l2 <= r2) ans[k++] = a[l2++];
for(int i = l; i <= r; i++){
a[i] = ans[i];
}
}
以上是合并的过程,聪明的你是否已经想到了问题解决的方法,如果能递归将要排序的数列一直二分下去,直到只有一个元素,那么合并以后,得到的就是一个有序序列。
- 递归过程代码:
void mergeSort(int l, int r){
if(l >= r) return ;
int mid = (l+r) >> 1;
mergeSort(l, mid);
mergeSort(mid+1, r);
mergeArray(l, mid, r);
}
如果要求逆序对数,只需要在合并的过程中,添加一个计数的变量即可。注意,如果当左边的序列某元素大于右边序列的某元素,那么左边序列这个元素包括他后面的元素都大于右边序列的这个元素,(因为序列本身是有序的)。
void mergeArray(int l, int mid, int r){
int l1 = l, r1 = mid;
int l2 = mid+1, r2 = r;
int k = l1;
while(l1 <= r1 && l2 <= r2){
if(a[l1] < a[l2]){
ans[k++] = a[l1++];
}else{
cnt += (r1-l1+1); // 逆序对数
ans[k++] = a[l2++];
}
}
while(l1 <= r1) ans[k++] = a[l1++];
while(l2 <= r2) ans[k++] = a[l2++];
for(int i = l; i <= r; i++){
a[i] = ans[i];
}
}
最后
以上就是无心发夹为你收集整理的归并排序的实现及利用其求逆序对数的全部内容,希望文章能够帮你解决归并排序的实现及利用其求逆序对数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复