學習《演算法導論》第二章 合併排序 總結

2021-07-04 22:40:27 字數 2600 閱讀 4844

分治策略:將原問題劃分成n個規模較小而結構與原問題相似的子問題;遞迴地解決這些子問題,然後再合併其結果,就得到原問題的解.

分治模式一般有三個步驟:

分解:將原問題分解成一系列子問題

解決:遞迴地解決各子問題

合併:將子問題的結果合併成原問題的解

合併排序直觀地操作如下:

分解:將n個元素分成n/2個元素的子串行

解決:用合併排序法對兩個子串行遞迴地排序

合併:合併兩個已排序的子串行以得到排序結果

單個元素被視為是已排好序的,這樣就能退出遞迴. 合併排序的關鍵是合併步驟、合併兩個已排好序的子串行. 為此,我們引入乙個輔助過程merge(a, p, q, r),其中a是乙個陣列,p、q和r是下標,假設子陣列a[p..q]和a[q+1..r]都已排好序,並將它們合併成乙個已排好序的陣列a[p..r].下面先給出合併過程的偽**:

merge(a,p, q, r) 

1 n1

2 n2

3 create arrays l[1..n1+1] and r[1..n2+1]

4 for i

l[i]

6 for j

r[j]

8l[n1+1]

9r[n2+1]

10 i

11 j

12 for k

13do

ifl[i] <= r[j]

14then

a[k]

15 i

16else

a[k]

17 j

由以上的偽**可知:merge過程的時間代價為θ(n). 此處n = r – q+1.

下面就可以講合併排序了,merge過程是合併排序的乙個子程式. 下面的merge-sort(a, p,r)對子陣列a[p..r]進行排序. 偽**如下:

merge-sort(a, p, r)

1if p < r

2then q

3merge-sort(a, p, q)

4merge-sort(a, q + 1, r)

5merge(a, p, q, r)

下圖自底向上地說明了當n為2的冪時,整個過程的操作:

為問題分析方便,這裡假設n為2的冪次方. 當n > 1時,將執行時間作如下的分解:

分解:這一步就是計算出子陣列的中間位置,常量時間,d(n) = θ(1).

解決:遞迴地解兩個規模為n/2的子問題,時間為2t(n/2).

合併:merge過程上面分析了,執行時間為c(n) = θ(n).

所以,t(n) = 2t(n/2) +θ(n). 那這個執行時間是多少呢?這是乙個遞迴式,後面有專門章節介紹這個解法,可以用迭代法也可以用主定理得出:

t(n) = θ(nlgn).

下面用另一種「遞迴樹」來分析如何解遞迴式,假設n為2的冪次方.

如上a, b, c, d圖,它被逐步地進行了擴充套件以形成遞迴樹,在最後一圖,它完全的擴充套件了的遞迴樹有lgn+1層,而每一層的總代價為cn,因此總的執行時間代價為cnlgn+cn. 因此執行時間為θ(nlgn).

// 合併子問題

void merge (int* num, int begin, int middle, int end)

// 將子問題2中的元素存入right陣列

for (i = 0; i < n2; i++)

i = 0;

j = 0;

// 分別將哨兵存入left和right陣列中,作為判斷是否到達陣列末尾

left[n1] = max_value;

right[n2] = max_value;

for (int k = begin; k <= end; k++)

if (left[i] >= right[j])

}free(left);

free(right);

return;

}// 合併排序

void mergesort (int* num, int start, int end)

return;

}

演算法導論 第二章演算法入門 合併排序

include include include include using namespace std 讀入檔案 void inputfile vector vec 合併程式 void merge vector vec,int p,int r,int q for j 1 j n2 j 這個是作為哨兵...

演算法導論第二章(歸併排序)

歸併排序,主要思想是分治法。相當於兩堆已排序好的撲克牌,每一次選擇兩堆牌頂上較小的那乙個,放到合併堆。最壞情況o nlogn 平均情況o nlogn package chapter2 public class mergesort mergesortfunction arr,0,9 for int i...

演算法導論第二章之歸併排序

歸併演算法即一種分治策略,將大問題劃分為n個小問題,然後對n小問題求解組合成大問題的解。在使用遞迴的分治排序中,涉及三個問題 一 小問題的不可劃分的或者終止條件 二 陣列的拆分 三 已排序的兩個陣列的合併。以下 是不使用遞迴的分治排序演算法,考慮可以結合多執行緒,使速度更快。package main...