歸併排序是多次將兩個或兩個以上的有序表合併為乙個新的有序表。最簡單的歸併是二路歸併,即將兩個有序表合併為乙個有序表。二路歸併排序的基本思想是:將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...