基本排序算法之4——归并排序mergesort
归并排序理论上时间复杂度只有O(NlogN),但是其中存在过多临时内存分配和copy操作而不适用于内存排序,却是外部排序的基本思路。下面是我的实现:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int g=0;
/*a,b is input array
* c is output array
* size of c is na+nb
*/
template<typename T>
void merge(T a[],int na,T b[],int nb,T c[])
{
T* pa=a;
T* pb=b;
T* pt= new T[na+nb];
int i=0,j=0,k=0;
while(i<na+nb)
{
while(j<na && k<nb && pa[j]<=pb[k])
{
pt[i++]=pa[j++];
}
while(j<na && k<nb && pb[k]<=pa[j])
{
pt[i++]=pb[k++];
}
if(j==na){
while(k<nb)
pt[i++]=pb[k++];
break;
}
if(k==nb){
while(j<na)
pt[i++]=pa[j++];
break;
}
}
cout<<"merge"<<g++<<":";
for(int i=0;i<na+nb;i++)
{
c[i]=pt[i];
cout<<c[i]<<' ';
}
cout<<endl;
delete []pt;
}
template<typename T>
void mergesort(T a[],int n)
{
if(n<=1)return;
int m=n/2;
mergesort(a,m);
mergesort(a+m,n-m);
merge(a,m,a+m,n-m,a);
}
template<typename T>
void show(T a[],int n)
{
for(int i=0;i<n;++i)
{
cout<<a[i]<<' ';
}
cout<<endl;
}
int main()
{
int l1[]={2,7,9,12};
int l2[]={3,6,8,11};
int l3[8];
merge(l1,4,l2,4,l3);
int a[]={9,3,6,2,7,5,8,0,4,1};
mergesort(a,10);
show(a,10);
return 0;
}
一些注意要点:
1.归并排序是归并算法的一个应用,所以要先实现归并算法,排序的时候先递归后操作。(如果递归算法是在第一层处理数据然后处理分支数据就是【先操作后递归】,如果是先分支从最后的分支开始处理数据向第一层合并,就是【先递归后操作】)。
2.尽量不要递归申请内存,那样会申请大量临时内存,这些内存的数据要保存又要大量的copy操作。
3.使用链表排序就不用临时分配内存也不用频繁copy。
4.循环嵌套的逻辑一次不一定写正确,先用while嵌套,逻辑更清晰。
寻找信心决心和贪心的一致性,达到情绪和环境的平衡,做到行动和思维一致才叫真正的行动。

浙公网安备 33010602011771号