歸併排序及模板

歸併排序理解

歸併排序的主要操作如下:
(1)分解。把初始序列分成長度相同的左、右兩個子序列,然後把每個子序列再分成更小的兩個子序列,直到子序列只包含一個數。這個過程用遞歸實現。
(2)求解子問題,對子序列排序。最底層的子序列只包含一個數,其實不用排序。
(3)合併。歸併兩個有序的子序列,這是歸併排序的主要操作。比如下面舉例,把a[ ]分成兩個子序列,比較後存進b[ ],假設兩個子序列已經分別排好序。
過程如下(有點醜…將就一下):

在這裏插入圖片描述
在這裏插入圖片描述

只要有一個子序列結束,就可以把另一個子序列後面的都放進去,因爲是排好序的

歸併排序的時間複雜度:對n個數進行排序:

  • 需要log2(n)趟歸併。

在這裏插入圖片描述

  • 在每一趟歸併中有很多次合併操作。共需O(n)次比較。所以時間複雜度爲

在這裏插入圖片描述

歸併排序模板

輸入n個數,對n個數進行排序。

#include<iostream>

using namespace std;

const int N=1e6 + 10;

int n;
int q[N],temp[N];
void merge(int q[],int l,int r)
{
	if(l >= r) return;//滿足條件不再往下進行
	
	int mid = (l + r)/2;
	
	merge(q,l,mid),merge(q,mid+1,r);//左右分開遞歸 
	
	int k=0,i=l,j=mid+1;//k表示temp裏個數,i指向左子序開頭,j指向右子序開頭 
	while(i <= mid && j<= r)
		if(q[i] <= q[j]) temp[k++]=q[i++];
		else temp[k++]=q[j++];
	while(i <= mid) temp[k++ ]=q[i++ ];//若左半邊沒循環完 全部拿出來 
	while(j <= r) temp[k++ ] = q[j++ ];//若右半邊沒循環完 全部拿出來 
	
	for(i = l,j = 0;i <= r;i++,j++) q[i]=temp[j];//把temp排好的賦給q[] 
} 

int main()
{
	cin>>n;
	for(int i = 0;i < n; i++) cin>>q[i];
	
	merge(q,0,n-1);//從0~n-1
	
	for(int i = 0;i < n; i++) cout<<q[i]<<" ";
	
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章