直接上代码:
//--------------------------------------------------------------------------归并排序:两次递归,一个合并
#include<iostream>
#include<cstdlib>
using namespace std;
#include<assert.h>
void Merge(int a[],int temp[],int lpos,int rpos,int rightend)
{
assert(a!=NULL && temp!=NULL && lpos>=0 && rpos>=0 && rpos<=rightend);
int tpos=lpos;
int lend=rpos-1;
int numelement=rightend-lpos+1;
while(lpos<=lend && rpos<=rightend)
{
if(a[lpos]<=a[rpos])
temp[tpos++]=a[lpos++];
else
temp[tpos++]=a[rpos++];
}
while(lpos<=lend)
{
temp[tpos++]=a[lpos++];
}
while(rpos<=rightend)
{
temp[tpos++]=a[rpos++];
}
for(int i=0;i<numelement;i++,rightend--)//********仅对操作的序列进行归并操作
{
a[rightend]=temp[rightend];
}
//for(int i=0;i<numelement;i++)
//{
// a[i]=temp[i];开始时,是这样写的,大错特错!
//}
}
void Msort(int a[],int temp[],int left,int right)
{
if(left<right)
{
int center=(left+right)/2;
Msort(a,temp,left,center);
Msort(a,temp,center+1,right);
Merge(a,temp,left,center+1,right);
}
}
void Print(int a[],int n)
{
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
int main()
{
int a[10]={1,5,6,3,4,2,9,8,10,7};
int temp[10];
Msort(a,temp,0,9);
Print(a,10);
return 0;
}
快速排序算法是以选择为基础(首先选择枢纽元),而归并排序是以归并操作为基础的;
从某种意义上来说,选择和归并操作时互补的,因为选择操作是将一个文件分解成两个独立的文件,而归并操作时将两个独立的文件合并成一个文件;
快速排序包括一个选择操作过程,后跟两个递归调用,而归并排序是两个递归调用之后是一个归并过程。(好好理解)
归并排序最显著的特性是:无论是什么样的输入,它对N个元素的排序所需时间与NlogN成正比。
归并排序的运行时间主要取决于输入数据的个数,对输入数据的顺序不太敏感。
归并排序是一种稳定的排序算法,而快速排序和堆排序不是很稳定。
虽然归并排序的运行时间是0(NlogN)(平均,最优,最差都是这样),但是其很难用于主存排序,主要问题在于合并两个排序的表需要线性附加内存(最差空间复杂度O(n)),在整个算法中还要花费将数据拷贝到临时数组再拷贝回来这样一些附加性工作,其结果严重放慢了排序的速度。