C 資料結構 歸併排序

2021-09-12 02:23:57 字數 3405 閱讀 2548

1、基本思想(自上而下):

將兩個的有序數列合併成乙個有序數列,我們稱之為"歸併"。歸併排序(merge sort)就是利用歸併思想對數列進行排序。

2、工作過程(自上而下)(對照下圖):

a)如圖所示的陣列進入mergesortup2down1函式,此時start=0,mid=3,end=7

(由於使用了遞迴,因此在mergesortup2down函式右方新增1意味著此為第一層函式

b)再次進入mergesortup2down1++,進入下一層,也就是mergesortup2down2函式,此時start=0,mid=1,end=3

(由於使用了遞迴,因此在mergesortup2down函式裡有兩個mergesortup2down函式,因此定義上方的函式為mergesortup2down++,下方為mergesortup2down1--

c)再次進入mergesortup2down2++ ,進入下一層,也就是mergesortup2down3函式,此時start=0,mid=0,end=1

d)再次進入mergesortup2down3++,進入下一層,也就是mergesortup2down4函式,由於start=mid=0,因此return,返回mergesortup2down3++函式。

e)在mergesortup2down3繼續執行 mergesortup2down3--,由於mid+1=end=1,進入下一層時會觸發return條件,因此return。

f)在mergesortup2down3繼續執行merge函式,融合a[start...mid] 和 a[mid+1...end],它們排序成乙個有序空間a[start...end],即a[0...1]。

g)執行完後,由於mergesortup2down3函式執行完,因此跳到mergesortup2down2執行mergesortup2down2--。

h)同理分析,如同一般,但start、mid、end數值發生改變,即mergesortup2down2--執行完

i)跳到mergesortup2down2執行merge函式,即融合a[0...1]和a[2...3]。

j)同樣上述步驟融合a[4...7],執行mergesortup2down1--

k)執行mergesortup2down1的merge函式,融合a[0...7]

3、基本思想(自下而上):

將待排序的數列分成若干個長度為1的子數列,然後將這些數列兩兩合併;得到若干個長度為2的有序數列,再將這些數列兩兩合併;得到若干個長度為4的有序數列,再將它們兩兩合併;直接合併成乙個數列為止。這樣就得到了我們想要的排序結果。(自下而上)

4、工作過程(自下而上):

通過"從下往上的歸併排序"來對陣列進行排序時:

1. 將陣列看作由8個有序的子陣列,,,,,,和組成。

2. 將這8個有序的子數列兩兩合併。得到4個有序的子樹列,,和。

3. 將這4個有序的子數列兩兩合併。得到2個有序的子樹列和。

4. 將這2個有序的子數列兩兩合併。得到1個有序的子樹列。

5、複雜度:

6、源**:

#include using namespace std;

/** 將乙個陣列中的兩個相鄰有序區間合併成乙個

** 引數說明:

* a -- 包含兩個有序區間的陣列

* start -- 第1個有序區間的起始位址。

* mid -- 第1個有序區間的結束位址。也是第2個有序區間的起始位址。

* end -- 第2個有序區間的結束位址。

*/void merge(int* a, int start, int mid, int end)

while (i <= mid)

tmp[k++] = a[i++];

while (j <= end)

tmp[k++] = a[j++];

// 將排序後的元素,全部都整合到陣列a中。

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

a[start + i] = tmp[i];

delete tmp;}/*

* 歸併排序(從上往下)

** 引數說明:

* a -- 待排序的陣列

* start -- 陣列的起始位址

* endi -- 陣列的結束位址

*/void mergesortup2down(int* a, int start, int end)

/** 對陣列a做若干次合併:陣列a的總長度為len,將它分為若干個長度為gap的子陣列;

* 將"每2個相鄰的子陣列" 進行合併排序。

*v* 引數說明:

* a -- 待排序的陣列

* len -- 陣列的長度

* gap -- 子陣列的長度

*/void mergegroups(int* a, int len, int gap)

// 若 i+gap-1 < len-1,則剩餘乙個子陣列沒有配對。

// 將該子陣列合併到已排序的陣列中。

if (i + gap - 1 < len - 1) }

/** 歸併排序(從下往上)

** 引數說明:

* a -- 待排序的陣列

* len -- 陣列的長度

*/void mergesortdown2up(int* a, int len)

int main()

{ int i;

int data[10];

int n = (sizeof(data)) / (sizeof(data[0]));

for (int i = 0; i <= n - 1; ++i)

data[i] = i;

for (int i = n - 1; i >0; --i)

swap(data[i], data[rand() % i]);

cout << "before sort:";

for (i = 0; i

資料結構 歸併排序

排序 sort 或分類 內部排序方法可以分為五類 插入排序 選擇排序 交換排序 歸併排序和分配排序。歸併排序 include using namespace std 歸併排序中的合併演算法 void merge int a,int left,int center,int len int t int ...

資料結構 歸併排序

歸併排序,即merge sort,通過遞迴式的merge操作 merge即歸併 實現排序。演算法思想是分治思想 divide and conquer 歸併排序一般是遞迴實現的 時間複雜度o nlgn 遞迴都是一去一回,去的時候divide,回的時候conquer。表達欠提煉 1 divide,分 遞...

資料結構 歸併排序!!!

歸併排序 整體思想 將資料分成很多的部分,每次排序資料的一部分,然後將兩部分的資料進行整體排序,這樣一步一步將整體資料排序。如圖 注 將需要排序的資料進行分塊,當每個塊的資料足夠的少的時候就可以進行效率高的排序方法,當兩塊資料排序好的時候就可以將兩塊排序好的資料進行合併。具體實現方法 ifndef ...