您的位置:首页 > 编程语言 > C语言/C++

归并排序的C++实现(大众版)

2013-10-09 10:08 369 查看
归并排序的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=1
j=1
for 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著,侯捷/孟岩译
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: