1. 程式人生 > 實用技巧 >純手擼——歸併排序

純手擼——歸併排序

思想:

  • 分治思想——把一個複雜龐大的問題分解成一個個小的問題去解決(就好比輔導員管班長,班長管寢室長,寢室長管寢室成員)
  • 歸併排序,就是將待排序的數分成兩半後排好序,然後再將兩個排好序的序列合併成一個有序序列
  • 需要開闢輔助空間,在合併時運用(如下圖,假設將最後的arr看成新的空間,就是不斷取出最小的元素放在裡面比較一下,取完後這個新空間裡的元素有序)

閱讀篇:慧能大師講解歸併排序

看圖入門:

程式碼實現(難度在合併,理解後還算簡單):

//將a[left...center]和a[center+1...right]兩個有序數組合併成一個有序陣列
void merge(int a[],int tmp[],int left,int center,int right)
{
	int i=left;
	int j=center+1;
	//比較結果暫放入tmp
	for(int k=left;k<=right;k++)
	{
		//若左邊陣列取完,則比較完成,直接將右邊陣列copy到臨時陣列
		//右邊陣列同理
		if(i>center)
		{
			tmp[k]=a[j++];
		}
		else if(j>right)
		{
			tmp[k]=a[i++];
		}
		else if(a[i]<=a[j])
		{
			tmp[k]=a[i++];
		}
		else
		{
			tmp[k]=a[j++];
		}
	}
	//再將排好序的臨時陣列回copy
	for(int h=left;h<=right;h++)
	{
		a[h]=tmp[h];
	}
}

void MergeSort(int a[],int tmp[],int left,int center,int right)
{
	if(left<right)
	{
		//[分]:陣列一分為二
		int center=(left+right)/2;
		//[治]:將左邊陣列排序
		MergeSort(a,tmp,left,center);
		//[治]:將右邊陣列排序
		MergeSort(a,tmp,center+1,right);
		//[合]:合併兩個有序陣列
		merge(a,tmp,left,center,right);
	}
}