归并排序的C++实现(大众版)
来源:互联网 发布:超星泛雅网络教学平台 编辑:程序博客网 时间:2024/06/04 08:06
归并排序的C++实现(大众版)
归并排序,是利用分治策略而成的一个典型应用。它将n个元素分成各含n/2个元素的子序列;然后再用合并排序法对两个子序列递归地排序;最后合并两个已排序的子序列,以得到排序结果。在对子序列排序时,对于单个元素,被视为已序,也就可以认为递归结束。其运行时间为Θ(nlogn)
归并排序的分解过程中,MERGE-SORT伪代码如下:
MERGE-SORT(A,p,r)if p<r then q=[(p+r)/2] MERGE-SORT(A,p,q) MERGE-SORT(A,q+1,r) MERGE(A,p,q,r)
在一段序列中,先利用左端位置p和右端位置r取得中间位置q,然后对一分为二的序列进行多次拆分直到只剩1个元素,最后再用MERGE对已序区间进行合并。
而在归并排序的合并过程中,MERGE伪代码如下:
MERGE(A,p,q,r)n1=q-p+1 //左段子序列的起始位置n2=r-q //右段子序列的起始位置create arrays L[1..n1+1]and R[1..n2+1]for i=1 to n1 L[i]=A[p+i-1]for j=1 to n2 R[i]=A[q+j]L[n1+1]=∞R[n2+1]=∞i=1j=1for k=p to r if (L[i]<=R[j]) A[k]=L[i] i=i+1 else A[k]=R[j] j=j+1
在合并两个已序子序列时,先用辅助序列L和R将A中元素分开存储,然后再通过比较两个子序列所指向的哨兵元素,选更小的放入主序列A中;最后当某一个子序列都完全放入主序列A后,再将另一个子序列的剩余所有元素一起放入主序列A中。伪代码中的正无穷符号,就是为了标记序列尾的。
最后贡献出归并排序的C++实现,与伪代码相比做了一些改变,不过其主体思想如出一辙:
#include<iostream>#include<vector>#include<algorithm>#include<iterator>template<typename T>void mymerge(std::vector<T>& a,int left,int middle,int right);template<typename T>void mergesort(std::vector<T>& a,int left,int right);template<typename T>void print(const std::vector<T>& a);template<typename T>void mergesort(std::vector<T>& a,int left,int right){ int middle; if (left<right) { middle=(int)((left+right)/2); mergesort(a,left,middle); //递归拆分左半边数组 mergesort(a,middle+1,right); //递归拆分右半边数组 mymerge(a,left,middle,right); //合并数组 }}template<typename T>void mymerge(std::vector<T>& a,int left,int middle,int right){ int n1,n2,i,j,k; n1=middle-left+1; n2=right-middle; T* Left=new T[n1]; T* Right=new T[n2]; for (i=0;i<n1;i++) Left[i]=a[left+i]; for (j=0;j<n2;j++) Right[j]=a[middle+1+j]; i=j=0; k=left; while (i<n1 && j<n2) //将数组元素值两两比较,并合并到a数组 { if (Left[i]<=Right[j]) a[k++]=Left[i++]; else a[k++]=Right[j++]; } for (;i<n1;i++) //如果左数组有元素剩余,则将剩余元素合并到a数组 a[k++]=Left[i]; for (;j<n2;j++) //如果右数组有元素剩余,则将剩余元素合并到a数组 a[k++]=Right[j]; delete []Right; delete []Left;}template<typename T>void print(const std::vector<T>& a){ std::ostream_iterator<T>out(std::cout," "); copy(a.begin(),a.end(),out); std::cout<<std::endl;}int main(){std::vector<int> a;a.push_back(5);a.push_back(2);a.push_back(0);a.push_back(1);a.push_back(3);a.push_back(7);a.push_back(9);a.push_back(4);a.push_back(8);a.push_back(6);mergesort(a,0,a.size()-1);print(a); //输出最后归并排序的结果 std::cin.sync();std::cin.get();}
参考文献:
1.《算法导论》2nd Thomas H.Cormen , Charles E.Leiserson , Ronald L.Rivest , Cliford Stein 著,潘金贵、顾铁成、李成法、叶懋译
2.《数据结构与算法分析 C++描述》 第3版 Mark Allen Weiss著,张怀勇等译
3.《C++标准模板库 -自修教程及参考手册-》 Nicolai M.Josuttis著,侯捷/孟岩译
- 归并排序的C++实现(大众版)
- C语言实现的归并排序
- 归并排序的C代码实现
- 归并排序的C语言实现
- C语言二分归并排序的实现
- C语言归并排序算法的实现
- 归并排序的C语言实现
- 归并排序的实现(排序算法c语言描述)
- 排序算法的C语言实现-归并排序
- 合并排序(归并排序)的C语言实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 关于数据库一致改关闭下redo日志文件丢失的处理办法的总结
- uboot移植过程
- PEX原理
- c-指针学习篇前言
- 如何让表单服务成为互联网基础服务?
- 归并排序的C++实现(大众版)
- PL/SQL Profiler 剖析报告生成html
- 线性内存分配
- sleep和wait的区别
- 书上的链表小程序
- linux/Ubuntu 下使用 java 调用 so 动态链接库详细步骤
- 硝烟中的Scrum和XP-我们如何实施Scrum 9)演示 10)回顾 11)休整
- Request.UrlReferrer 同Request.Url获取数据
- JLINK烧写BIN文件到nand、norflash、SDRAM