码迷,mamicode.com
首页 > 编程语言 > 详细

归并排序

时间:2018-08-18 17:55:38      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:技术分享   display   大于   e30   归并排序   思想   复杂度   二分   复杂   

归并排序体现了分治思想,时间复杂度是O(nlogn),空间复杂度是O(n)。

归并排序是将序列不断二分,最终分成单个元素,再两两合并,最终达到整个序列有序。

技术分享图片
 1 void msort(int l,int r) {
 2     if(l==r) return; //划分到单个元素就返回
 3     int m=l+(r-l)/2,p=l,q=m+1,k=l;
 4     msort(l,m); //划分左右序列
 5     msort(m+1,r);
 6     while(p<=m||q<=r) //将左右序列合并成有序序列
 7         if(q>r||(a[p]<a[q]&&p<=m)) T[k++]=a[p++];
 8         else T[k++]=a[q++];
 9     for(k=l;k<=r;++k) a[k]=T[k]; //将合并后的序列放到原序列中
10 }
归并排序

归并排序的效率很高,而且不像快排那样会被特殊数据卡掉,只不过需要辅助内存。归并排序还有一种用途,就是统计逆序对。逆序对是指在一个序列中位置与值不对应的数对,如:1 3 2 4 7,就有(3,2),(3,4),(3,7)这三对逆序对。朴素的算法需要两层循环,复杂度是O(n^2)的,而归并排序本身的特性却可以让我们方便地统计逆序对。由于合并左右两个序列时,两个序列已有序,因此当出现右边元素大于左边元素时,此时左边序列剩余元素个数就是逆序对个数的一部分。

技术分享图片
 1 void msort(int l,int r) {
 2     if(l==r) return; //划分到单个元素就返回
 3     int m=l+(r-l)/2,p=l,q=m+1,k=l;
 4     msort(l,m); //划分左右序列
 5     msort(m+1,r);
 6     while(p<=m||q<=r) //将左右序列合并成有序序列
 7         if(q>r||(a[p]<a[q]&&p<=m)) T[k++]=a[p++];
 8         else T[k++]=a[q++],cnt+=m-p+1; //顺便统计逆序对个数
 9     for(k=l;k<=r;++k) a[k]=T[k]; //将合并后的序列放到原序列中
10 }
归并排序(统计逆序对)

 

归并排序

标签:技术分享   display   大于   e30   归并排序   思想   复杂度   二分   复杂   

原文地址:https://www.cnblogs.com/Mr94Kevin/p/9497601.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!