排序专题之归并排序
2015-08-10 15:16
141 查看
归并排序:
基本思想是将两个或两个以上有序表合并成一个新的有序表。
假设初始序列含有n个记录,首先将这n个记录看成n个有序的子序列,
每个子序列的长度为1,然后两两归并,得到?n/2?个长度为2(n为奇数时,
最后一个序列的长度为1)的有序子序列;在此基础上,再进行两两归并,
如此重复,直至得到一个长度为n的有序序列为止。这种方法被称作2-路归并排序。
下面请看代码实现:
代码一:
优化避免后面的t1 t2 要查看其长度,把后面的子数组的
顺序在转移的时候替换顺序;
归并排序中一趟归并中要多次用到2-路归并算法,
一趟归并排序的操作是调用n/2h次算法merge 将r1[1…n]中前后
相邻且长度为h的有序段进行两两归并,得到前后相邻、长度为2h的有序段,并存放在r[1…n]中,
其 时间复杂度为O(n)。整个归并排序需进行m(m=log2n)趟2-路归并,
所以归并排序总的时间复杂度为O(nlog2n)。
在实现归并排序时,需要和待排记录等数量的辅助空间,空间复杂度为O(n)。
归并排序的最大特点是,它是一种稳定的排序方法
基本思想是将两个或两个以上有序表合并成一个新的有序表。
假设初始序列含有n个记录,首先将这n个记录看成n个有序的子序列,
每个子序列的长度为1,然后两两归并,得到?n/2?个长度为2(n为奇数时,
最后一个序列的长度为1)的有序子序列;在此基础上,再进行两两归并,
如此重复,直至得到一个长度为n的有序序列为止。这种方法被称作2-路归并排序。
下面请看代码实现:
代码一:
void Mergesort(Record s[],Record a[],int left,int right) { int middle; if(left<right) { middle=(left+right)/2; Mergesort(s,a,left,middle); Mergesort(s,a,middle+1,right); guibing(s,a,left,right,middle); } } void guibing(Record s[],Record a[],int left,int right,int middle) { int t1,t2,i,j; for(i=left;i<right;i++) { a[i]=s[i]; } t1=left,t2=middle+1; i=left; while(t1<=middle&&t2<=right) { if(a[t1]<=a[t2]) s[i++]=a[t1++]; else s[i++]=a[t2++]; } while(t1<=middle) { s[i++]=a[t1++]; } while(t2<=right) { s[i++]=a[t2++]; } }
优化避免后面的t1 t2 要查看其长度,把后面的子数组的
顺序在转移的时候替换顺序;
void Mergesort(Record s[],Record a[],int left,int right) { int middle; if(right-left+1>28) { middle=(left+right)/2; Mergesort(s,a,left,middle); //左一半进行递归 Mergesort(s,a,middle+1,right); //右一半进行递归 guobing(s,a,left,right,middle); } else charu(&a[left],right-left+1);//若序列短的 直接用插入排序 } void guibing(Record s[],Record a[],int left,int right,int middle) { int t1,t2,i,j,k; for(i=left;i<=middle;i++) { a[i]=s[i]; } for(j=1;j<=right-middle;j++) { a[right-j+1]=s[j+middle]; } for(t1=left,t2=right,k=left;k<=right;k++) { if(a[t1]<=a[t2]) { s[k]=a[t1++]; } else s[k]=a[t2--]; } }
归并排序中一趟归并中要多次用到2-路归并算法,
一趟归并排序的操作是调用n/2h次算法merge 将r1[1…n]中前后
相邻且长度为h的有序段进行两两归并,得到前后相邻、长度为2h的有序段,并存放在r[1…n]中,
其 时间复杂度为O(n)。整个归并排序需进行m(m=log2n)趟2-路归并,
所以归并排序总的时间复杂度为O(nlog2n)。
在实现归并排序时,需要和待排记录等数量的辅助空间,空间复杂度为O(n)。
归并排序的最大特点是,它是一种稳定的排序方法
相关文章推荐
- PC110101(3n+1问题)(3n+1 Problem)
- POJ 3687 Labeling Balls(拓扑排序)
- 第一个项目所学记录
- NSDictionary及NSMutableDictionary
- android 水平平分两个按钮
- Redis 存储字符串和对象
- phpstorm设置编码 gbk gb2312 支持 asp
- ThreadLocal源码解析
- Sublime Text 3技巧:支持GB2312和GBK编码
- php截取指定字符串之间的字符串的类
- ArcEngine编辑保存错误:Unable to create logfile system tables
- 【十九】练习ACL操作时遇到的问题及解决办法
- JavaWeb 注解Annotation的使用
- 配置php生产环境——notice warning消除
- 解决c/c++的sequence points和side effects问题
- [leetcode-96]Unique Binary Search Trees(c++)
- 卷积的物理意义
- 互联网MySQL开发规范
- Python uuid模块
- [经典算法] 字符串搜索Boyer-Moore