二路歸並排序


二路歸並排序主要運用了“分治算法”,分治算法就是將一個大的問題划分為n個規模較小而結構相似的子問題。

這些子問題解決的方法都是類似的,解決掉這些小的問題之后,歸並子問題的結果,就得到了“大”問題的解。

  二路歸並排序主旨是“分解”與“歸並”

  分解:  

    1.將一個數組分成兩個數組,分別對兩個數組進行排序。

    2.循環第一步,直到划分出來的“小數組”只包含一個元素,只有一個元素的數組默認為已經排好序。

  歸並:

    1.將兩個有序的數組合並到一個大的數組中。

    2.從最小的只包含一個元素的數組開始兩兩合並。此時,合並好的數組也是有序的。

              

        圖1. 歸並排序過程                                  圖2. 合並兩個有序數組

                                                                                          

舉例說明:

  1.圖中原始數組為{2,4,7,5,8,1,3,6},數組中元素的個數為8個。首先將8個元素的數組二分,每次分解后,

數組中元素的數目為原數組的一半。直到分解為只含有一個元素的數組。

  2.將小的數組按序合並,每次合並后數組的大小為上層數組的一倍。此時數組中的元素都是按序排列的。

  3.在合並兩個有序數組。如圖2

下面的是自頂向下遞歸實現2路歸並排序:

#include  <iostream>
using namespace std;

void  Merge(int * a, int low, int mid, int high)
{
	int i = low, j = mid + 1, p = 0;//對應a數組的下標
	int * r = new int[high - low + 1];//申請另一個對應大小的數組來存放排好序的數據
	while (i <= mid && j <= high)
	{
		r[p++] = (a[i] <= a[j]) ? a[i++] : a[j++];
	}
	while (i <= mid)
		r[p++] = a[i++];
	while (j <= high)
		r[p++] = a[j++];
	for (p = 0, i = low; i <= high; p++, i++)
		a[i] = r[p];//最后再把有序數據存進a數組中,使得a數組對應部分數據有序
	delete[] r;
}
//自頂向下(遞歸實現)
void MSort(int *a, int low, int high)
{
	if (low<high)
	{
		int mid = (low + high) / 2;
		MSort(a, low, mid);
		MSort(a, mid + 1, high);
		Merge(a, low, mid, high);
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	int a[] = { 2,4,7,5,8,1,3,6 };
	int n = sizeof(a) / sizeof(int);
	MSort(a, 0, n - 1);
	for (int i = 0; i<n; i++)
		cout << a[i] << " ";
	cout << endl;
	system("PAUSE");
	return 0;
}

  

  

參考資料:《算法導論》2.1章節


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM