資料結構與演算法 十個排序演算法之五 歸併排序

2022-06-03 16:00:15 字數 3450 閱讀 6936

歸併排序(merge sort)是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。

作為一種典型的分而治之思想的演算法應用,歸併排序的實現由兩種方法:

和選擇排序一樣,歸併排序的效能不受輸入資料的影響,但表現比選擇排序好的多,因為始終都是 o(nlogn) 的時間複雜度。代價是需要額外的記憶體空間。

當兩個組資料已經有序,我們可以通過如下方式讓兩組資料快速有序,13

6724

68我們可以依次從兩組中取最前面的那個最小元素依次有序放到新的陣列中,然後再把新陣列 中有序的資料拷貝到原陣列中快速完成排序.12

3456

78依靠這種思想,有了如下的排序方法!

具體步驟:

對於下面這一組待排序的陣列

163161

158165

171170

163159

162先以中間為界,把其均分為 a 和 b 兩個陣列(如果是奇數個,允許兩組數相差乙個)

a組:

163161

158165

b組:

171170

163159

162如果 a 和 b 兩組資料能夠有序,則我們可以通過上面的方式讓陣列快速排好序。 此時,a 組有 4 個成員, b 組有 5 個成員, 但兩個陣列都無序,然後我們可以採用分治法繼 續對 a 組和 b 組進行均分,以 a 組為例,又可以均分 a1 和 a2 兩個組如下:

a組:

163161

b組:

158165

均分後,a1 組和 a2 組仍然無序,繼續利用分治法細分,以 a1 組為例,a1 又可分成如下 兩組

a11 組:

163a12 組:

161陣列細分到乙個元素後,這時候,我們就可以採用歸併法借助乙個臨時陣列將陣列 a1 有序化! a2 同理!

a組:

161163

b組:

158165

依次類推,將 a1 組和 a2 組歸併成有序的 a 組, b 組同理!

a組:

158161

163165

b組:

159162

163170

171最後,將 a 和 b 組合並,就得到了完整的有序的結果!

158159

161162

163163

165170

171演示總結:

申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列;

設定兩個指標,最初位置分別為兩個已經排序序列的起始位置;

比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置;

重複步驟 3 直到某一指標達到序列尾;

將另一串行剩下的所有元素直接複製到合併序列尾。

**實現:

1 #include 2 #include 3 #include 45

void mergeadd_demo(int arr, int left, int mid, int

right)6;

8int i = left;   //

指向左邊陣列最小的元素位置

9int j = mid;    //

指向右邊陣列最小的元素位置

10int k = 0;   //

臨時陣列的下標

11while( iright)

1217

else

1821}22

23while(i

2427

28while(j<=right)

2932

33//

把 temp 中的內容拷貝到 arr 陣列中

34 memcpy(arr+left, temp, sizeof(int) * (right - left + 1

));3536}

3738

void mergeadd(int arr, int left, int mid, int right, int *temp)39;

41int i = left; //

指向左邊陣列最小的元素位置

42int j = mid; //

指向右邊陣列最小的元素位置

43int k = left; //

臨時陣列的下標

4445

while( iright)

4651

else

5255}56

57while(i

5861

62while(j<=right)

6366

67//

把 temp 中的內容拷貝到 arr 陣列中

6869 memcpy(arr+left, temp+left, sizeof(int) * (right - left + 1

));7071}

7273

void mergesort(int arr, int left, int right, int *temp) //

歸併排序

7483}84

85int main(void)86

;88int len = sizeof(beauties)/sizeof(beauties[0

]);89

int *temp = new

int[len];

9091

//int mid = len/2;

92 mergesort(beauties, 0, len - 1

, temp);

9394

//mergeadd(beauties, 0, mid, len-1, temp);

95 printf("

執行合併:\n");

9697

for(int i=0; i)

98101

102 system("

pause");

103104

return0;

105 }

資料結構與演算法 十個排序演算法

排序演算法是 資料結構與演算法 中最基本的演算法之一,排序演算法可以分為內部和外部排序。內部排序 資料記錄在記憶體中進行排序。外部排序 因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。常見內部排序演算法 插入排序 希爾排序 選擇排序 氣泡排序 快速排序 堆排序 基數排序等。用...

資料結構與演算法 十個排序演算法之九 桶排序

桶排序是計數排序的公升級版。它利用了函式的對映關係,高效與否的關鍵就在於這個對映函式的確定。為了使桶排序更加高效,我們需要做到這兩點 在額外空間充足的情況下,盡量增大桶的數量 使用的對映函式能夠將輸入的 n 個資料均勻的分配到 k 個桶中 同時,對於桶中元素的排序,選擇何種比較排序演算法對於效能的影...

資料結構與演算法 十個排序演算法之六 快速排序

快速排序是由 東尼 霍爾 所發展的一種排序演算法。在平均狀況下,排序 n 個專案要 n log n 次比較。在最壞狀況下則需要 n2 次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他 n log n 演算法更快,因為它的內部迴圈 inner loop 可以在大部分的架構上很有效率地被實現出...