排序演算法 歸併排序

2021-07-25 14:15:29 字數 2221 閱讀 4485

歸併排序是多次將兩個或兩個以上的有序表合併為乙個新的有序表。最簡單的歸併是二路歸併,即將兩個有序表合併為乙個有序表。二路歸併排序的基本思想是:將r[0..n-1]看作是n個長度為1的有序子表,然後進行兩兩二路歸併,得到[n/2](對n/2取整數)個長度為2(最後乙個子表的長度可能小於2)的有序子表;再次進行兩兩二路歸併,得到[n/4]個長度為4(最後乙個子表的長度可能小於4)的有序子表,...,直到得到乙個長度為n的有序表。

/**

* 歸併排序

** 演算法:歸併排序(merge sort)

* 輸入:待排序元素的陣列,待排序元素個數

* 輸出:

* 原理:將待排序的表r[0..n-1]看做是n個長度為1的有序子表,將這些子表兩兩歸併;將第一趟歸併得到的子表繼續兩兩歸併;重複上述操作,直到最後得到乙個長度為n的有序表

* 過程:

* 1)將待排序的表r[0..n-1]看做是n個長度為1的有序子表,將這些子表兩兩歸併,得到的子表的長度為2(最後乙個子表的長度可能不是2)

* 2)將第一趟歸併得到的所有子表繼續兩兩歸併,得到的子表的長度為4(最後乙個子表的長度可能不是4)

* 3) ...

* 4)重複上述操作,直到得到長度為n的有序表

* 5) ...

* 6)最終得到的r[0..n-1]中的元素遞增排序

** 時間複雜度為o(nlog2(n)),空間複雜度為o(n),穩定的排序方法

*/void mergesort(rectype r, int n)

/** * 目的:對整個表進行一趟歸併

* 作用:將r[0..n-1]中長度為length的有序子表,合併為長度為2length的有序子表

* 原理:在某趟歸併中,設各子表長度為length(最後乙個子表的長度可能小於length),則歸併前r[0..n-1]中共有[n/length]個有序子表:r[0..length-1],r[length..2length-1],...,r[[n/length]*length..n-1]。其中,[n/length]表示取整數

呼叫merge()函式將相鄰的一對子表進行歸併。

* 特殊情況:若子表個數為奇數,則最後乙個子表無序歸併;若子表個數為偶數,則要注意最後乙個子表的區間上界是n-1,最後乙個子表的長度可能小於length

* 過程:

* 1) 呼叫merge()函式將所有的長度為length的相鄰的一對子表歸併

* 2) 判斷剩餘乙個子表還是兩個子表

* 3)若還剩兩個子表,則歸併這兩個子表;否則,不做任何操作

* */

void mergepass(rectype r, int length, int n)

//餘下兩個子表,後者長度小於length

if (i + length < n) }

/** * 目的:將兩個有序表r[low..mid]和r[mid+1..high]直接歸併為乙個有序表

* 原理:每次從兩個有序表(遞增)中取出乙個元素進行關鍵字的比較,將較小者放入乙個區域性的暫存陣列r1中,最後將各有序表中餘下的部分直接複製到r1中,得到有序表r1

* 過程:

* 1) 初始化r1,用於儲存合併後的有序表

* 2) 分別從兩個有序表(遞增)中取出第乙個元素,比較它們的關鍵字大小,將關鍵字較小的元素放入r1中,並將該元素從原來的有序表中刪除

* 3)繼續從兩個有序表中取出第乙個元素進行比較,直至某乙個有序表中沒有任何元素可以取出來比較

* 4) ...

* 5) 將還有剩餘元素的有序表中的元素全部放入r1中

* 6) 得到的r1[0..high-low]中的元素遞增排序

* 7) 將r1中的元素複製回r中

* 8) 最終得到的r[low..high]中的元素遞增排序

* */

void merge(rectype r, int low, int mid, int high)

else //將第2有序表中的元素放入r1中

}//將第1有序表餘下部分複製到r1中

while (i <= mid)

//將第2有序表餘下部分複製到r1中

while (j <= high)

//將r1複製回r中

for (k = 0, i = low; i <= high; k++, i++)

r[i] = r1[k];

//釋放r1的空間

delete r1;

//free(r1);

}

排序演算法 歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...

排序演算法 歸併排序

include include define status int define max 20 typedef struct elemtype typedef struct sqlist void inital sqlist l 初始化 bool lt int i,int j void merge ...

排序演算法 歸併排序

歸併排序的思想其實完全是分治法的思想的體現,它完全遵循分治法的模式。這裡有必要再重提下分治法的思想 將原有的問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後再合併這些子問題的解來求得原問題的解。現在來看看歸併排序的操作 1 將等待排序的含有 n 個元素的序列分解成各具有 n...