排序演算法__歸併排序

Enjoy_process發表於2019-03-08

                                               排序演算法__歸併排序

 

 

一、介紹

歸併排序是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為二路歸併。注意歸併排序為穩定的排序。

 

二、C++實現

遞迴形式

#include<iostream>

using namespace std;

//對有序區間[l,mid)和[mid,r)進行合併 
void merge(int a[],int l,int mid,int r)
{
	int *temp=new int[r-l];//建立一個臨時陣列 
	int i=l,j=mid,k=0;//i和j分別是有序區間[l,mid)和[mid,r)的索引 
	while(i<mid&&j<r) 
	{
		if(a[i]<=a[j])//讓temp[k]等於較小者 
		  temp[k++]=a[i++];
		else
		  temp[k++]=a[j++];
	}
	while(i<mid) temp[k++]=a[i++];//如果[l,mid)區間還沒掃描完 
	while(j<r) temp[k++]=a[j++];//如果[mid,r)區間還沒掃描完 
	for(i=0;i<k;i++)//將有序的區間[l,r)寫到原陣列 
	  a[l+i]=temp[i];
}

//對區間[l,r)進行歸併排序 
void mergeSort(int a[],int l,int r)
{
	if(r-l==1) return;//區間[l,r)只有一個元素時遞迴結束 
	int mid=(l+r)>>1;
	mergeSort(a,l,mid);//對區間[l,mid)進行排序
	mergeSort(a,mid,r);//對區間[mid,r)進行排序
	merge(a,l,mid,r);//對有序區間[l,mid)和[mid,r)進行合併 
}

int main()
{
	int a[10]={100,90,80,70,60,50,40,30,20,10};
	printf("排序前:"); 
	for(int i=0;i<10;i++)
	  printf("%d ",a[i]);
	mergeSort(a,0,10);
	printf("\n排序後:");
	for(int i=0;i<10;i++)
	  printf("%d ",a[i]);
	return 0;
}

非遞迴形式

#include<iostream>

using namespace std;

//對有序區間[l,mid)和[mid,r)進行合併 
void merge(int a[],int l,int mid,int r)
{
	int *temp=new int[r-l];//建立一個臨時陣列 
	int i=l,j=mid,k=0;//i和j分別是有序區間[l,mid)和[mid,r)的索引 
	while(i<mid&&j<r) 
	{
		if(a[i]<=a[j])//讓temp[k]等於較小者 
		  temp[k++]=a[i++];
		else
		  temp[k++]=a[j++];
	}
	while(i<mid) temp[k++]=a[i++];//如果[l,mid)區間還沒掃描完 
	while(j<r) temp[k++]=a[j++];//如果[mid,r)區間還沒掃描完 
	for(i=0;i<k;i++)//將有序的區間[l,r)寫到原陣列 
	  a[l+i]=temp[i];
}

//對區間[l,r)進行歸併排序 
void mergeSort(int a[],int n)
{ 
	int len,i,j,mid;
	for(len=1;len<=n;len*=2)//區間的長度為len 
	{
		for(i=0;i+2*len<=n;i+=2*len)//對區間[i,i+2*len)進行排序 
	  	{ 
			merge(a,i,i+len,i+2*len);//對區間[i,i+len)和[i+len,i+2*len)進行合併 
	  	}
	  	//若 i+len<n,則剩餘一個子陣列沒有配對,將該子陣列合併到已排序的陣列中。
 		if(i+len<n) merge(a,i,i+len,n);
	}
}

int main()
{
	int a[10]={100,90,80,70,60,50,40,30,20,10};
	printf("排序前:"); 
	for(int i=0;i<10;i++)
	  printf("%d ",a[i]);
	mergeSort(a,10);
	printf("\n排序後:");
	for(int i=0;i<10;i++)
	  printf("%d ",a[i]);
	return 0;
}

三、時間複雜度

O(nlogn) 

 

相關文章