版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014183456/article/details/82965360
归并排序算法采用的是分治算法,即把两个(或两个以上)有序表合并成一个新的有序表,即把待排序的序列分成若干个子序列,每个子序列都是有序的,然后把有序子序列合并成整体有序序列,这个过程也称为2-路归并.一般来说,n个数据大致会分为logN层,每层执行merge的总复杂度为O(n), 所以总的复杂度为O(nlogn)。
归并排序包含不相邻元素的比较,但并不会直接交换。在合并两个已排序的数组时,如果遇到了相同的元素,只要保证前半部分数组优先于后半部分数组,相同元素的顺序就不会颠倒,所以归并排序属于稳定的排序算法。
归并排序算法虽然高效且稳定,但在处理过程中除了用于 保存输入数据的数组外,还要临时占用一部分的内存空间。
C++迭代法:
#include <iostream>
#include <algorithm>
using namespace std;
/*归并排序:两两排序好的数进行重新组排,归并排序是建立在归并操作上的一种有效的排序算法,
//该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
//将已有序的子序列合并,得到完全有序的序列;
//即先使每个子序列有序,再使子序列段间有序。
若将两个有序表合并成一个有序表,称为二路归并。 */
template <class T>
void Merge(T *initList,T *mergList,const int l,const int m,const int n)
{//initList初始数组 mergList归并好的数组 , l是第一个数组的下标,m是第二个数组的下标,n是数组个数
int i1,i2,result;
for(i1=l,i2=m+1,result=l;(i1<=m )&& (i2<=n); result++)
{
//进行比较
if(initList[i1]<=initList[i2]) //小的放进合并数组里面
{
mergList[result]=initList[i1];
i1++;
}
else
{
mergList[result]=initList[i2];
i2++;
}
}
copy(initList+i1,initList+m+1,mergList+result); //把剩下的直接拷贝到mergList里面
copy(initList+i2,initList+n+1,mergList+result);
}
template <class T>
void MergPass(T *initList,T *resultList,const int n,const int s)//n为元素个数,s为数组循环次数
{//一个数合并成两个数,这个过程中s=1,依次类推s=2....
int i;
for(i=1;i<n-2*s+1;i+=2*s)//进行合并
Merge(initList,resultList,i,i+s-1,i+2*s-1);
if((i+s-1)<n) //如果没有剩余的,就进行归并
Merge(initList,resultList,i,i+s-1,n);
else //如果有剩余的,就把剩下的复制下来
copy(initList+i,initList+n+1,resultList+i);
}
template<class T>
void MergeSort(T *a,const int n) //进行归并 n为数组个数
{
T *templist=new int[n+1]; //templist[0]不用
for(int l=1;l<n;l*=2) //l每次取值都是1,2,4,8...
{
MergPass(a,templist,n,l); //第一次归并
l*=2;
MergPass(templist,a,n,l); //循环使用数组a,不会资源浪费
}
delete []templist; //删除临时变量
}
int main()
{
//int a[]={0,23,47,81,95,7,14,39,55,62,74};
int x[]={0,23,47,81,95,7,14,39,55,62,74};
MergeSort(x,10);
for(int i=1;i<11;i++)
{
cout<<x[i]<<" ";
}
cout<<endl;
return 0;
}
C++递归法:
#include<iostream>
using namespace std;
template <class T>
void merge(T *a,int n,int left,int mid,int right)
{
//int L[maxn/2+2],R[maxn/2+2];
T *L=new T[n+1];
T *R=new T[n+1];
int n1=mid-left,n2=right-mid;
for(int i=0;i<n1;i++)
L[i]=a[left+i];
for(int i=0;i<n2;i++)
R[i]=a[mid+i];
L[n1]=R[n2]=1000; //这个数设置的比数组里面的任何数都要大。否则会出错
int i=0,j=0;
for(int k=left;k<right;k++)
{
if(L[i]<=R[j])
a[k]=L[i++];
else
a[k]=R[j++];
}
delete []L;
delete []R;
}
void mergesort(int a[],int n,int left,int right)
{
if(left+1<right)
{
int mid=(left+right)/2;
mergesort(a,n,left,mid);
mergesort(a,n,mid,right);
merge(a,n,left,mid,right);
}
}
void Merge(int a[],const int n)
{
mergesort(a,n,0,n);
}
int main()
{
// int a[maxn],n;
// cin>>n;
// for(int i=0;i<n;i++)
// cin>>a[i];
int a[]={23,47,81,95,7,14,39,55,62,74,26};
Merge(a,11);
for(int i=0;i<11;i++)
{
if(i)
cout<<" ";
cout<<a[i];
}
cout<<endl;
return 0;
}