基本排序算法之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嵌套,逻辑更清晰。

原文地址:https://www.cnblogs.com/jwk000/p/3117938.html