排序演算法(四) 歸併排序

2021-08-08 01:24:33 字數 2327 閱讀 8383

合併排序也即歸併排序,是將兩個或兩個以上的有序表合併成乙個新的有序表的操作,是分治法的乙個典型應用。

先使每個子串行有序(段內有序),再使子串行段間有序,最後合併後得到完全有序的序列。歸併排序可以使用遞迴實現,遞迴的條件是序列起始位置(startindex)小於序列結束位置(endindex),即序列元素大於 1。

先將原序列一分為二,再分別對子序列一和子串行二進行遞迴排序操作,並不斷對相鄰兩個序列執行歸併操作,直至序列完全有序。設子串行一為陣列 a,子串行二為陣列 b,合併的新序列為陣列 c。歸併的過程為:比較 a[i] 和 b[j] 的大小,若 a[i] 小於等於 b[j],則將第乙個有序表中的元素 a[i] 複製到 c[k] 中,並令 i 和 k 分別加上1;否則將第二個有序表中的元素 b[j] 複製到 c[k] 中,並令 j 和 k 分別加上 1,如此迴圈下去,直到其中乙個有序表的元素被取完,然後將另乙個未取完元素的有序表中的剩餘元素複製到 c 中,新增到已有元素後面。最後將新序列 c 拷貝並覆蓋原序列,完成對原序列的排序操作。

二、**及注釋:

void merge(int *arra, int *arrb, int startindex, int middleindex, int endindex)

else //若序列二的元素小於序列一的元素

k++; //新序列每增加乙個元素則下標+1

} while (i < middleindex + 1) //若序列二取完了而序列一未取完

while (j < endindex + 1) //若序列一取完了而序列二未取完

for (i = startindex; i <= endindex; i++) }

void mergesort(int *arra, int *arrb, int startindex, int endindex) //歸併排序需要跟原陣列同樣大小的陣列作為輔助空間

}

三、演算法效能分析:

當輸入規模為 n = 10000、20000、30000、40000、50000 時,執行程式,可以得到在不同輸入規模下,20 組隨機樣本資料執行歸併排序的單組執行時間及平均執行時間為:

理論上來說,歸併排序的時間複雜度為 o(nlogn)。同時,由上圖可以看出,當 n = 10000 時,20 組樣本排序的平均執行為 1.07594 ms。以輸入規模為 10000 的資料執行時間為基準點,則設理論上的平均執行時間為:t = o(nlogn),當 n 擴大兩倍時,t』 = o(2nlog2n) =o(2n(logn + log2)) = o(2nlogn + 2nlog2) ≈ o(2nlogn);同理 n 擴大 3 倍、4 倍、5 倍時,t』 ≈ o(3nlogn)、o(4nlogn)、o(5nlogn),相應地,實測耗時為:t』 = 2t、3t、4t、5t,代入t = 1.07594 ms,可以計算出合併排序的理論耗時及實測耗時。

所以,在相應輸入規模下,合併排序的理論執行時間為:

根據上表,可以作出歸併排序理論效率曲線和實測效率曲線如下:

如上圖表,是合併排序的理論效率曲線和實測效率曲線,其中位於上方的資料標籤是實測效率曲線的標註,位於下方的資料標籤是理論效率曲線的標註。由圖表我們可以看出,在問題規模較小時,合併排序的理論耗時和實測耗時時間相近,隨著問題規模的增大,實測耗時略高於理論耗時,並且可能隨著輸入規模的增大二者的差距會逐漸增大。

在歸併排序過程中,不斷地將待排序列一分為二,然後進行歸併排序操作。上述操作使用遞迴實現,將序列分為各個子串行直至子串行中僅有乙個元素,而後開始兩兩進行合併,合併成新的序列後退出深層遞迴返回上一層遞迴,再與剛才其餘序列合併的新序列進行兩兩合併,如此下去,直至序列完全有序。若待排序記錄為 n 個,則需要做 logn 趟歸併,每趟歸併的時間複雜度為 o(n),因此,總的時間複雜度為 o(nlogn),其曲線應當近乎符合線性關係,從上面的折線圖也可以比較直觀地看出,不管是理論效率曲線還是實測效率曲線,都基本符合線性關係。

在輸入規模較小時,合併排序的理論耗時和實測耗時時間相近,隨著問題規模的增大,實測耗時略高於理論耗時,並且可能隨著輸入規模的增大二者的差距會逐漸增大,原因可能是在 n 較小時,遞迴呼叫耗費時間對總時間影響不大,而隨著輸入規模地增大,遞迴呼叫的次數越來越多,系統對各個遞迴式的處理和協調耗費了更多的時間,從而對最終結果造成了一定的影響。當然,也可能跟程式執行時電腦的狀態有一定關係。

排序演算法四 歸併排序

歸併排序 思想 1 先對資料的整體進行劃分 把資料劃分為左右均等的兩部分,繼續劃分,直到資料分組有序為止 2 每個分組只剩下乙個元素則是有序的 3 把兩個部分 資料 歸併成乙個部分 逐次歸併 給定乙個輔助空間,給定乙個指標放在第乙個陣列的起始位置x1,給定另乙個指標放在另乙個陣列的起始位置x2,給定...

漫談經典排序演算法 四 歸併排序 合併排序

這是 漫談經典排序演算法系列 第四篇,解析了歸併排序。各種排序演算法的解析請參考如下 漫談經典排序演算法 一 從簡單選擇排序到堆排序的深度解析 漫談經典排序演算法 二 各種插入排序解析及效能比較 漫談經典排序演算法 三 氣泡排序 快速排序 漫談經典排序演算法 四 歸併排序 漫談經典排序演算法 五 線...

漫談經典排序演算法 四 歸併排序 合併排序

這是 漫談經典排序演算法系列 第四篇,解析了歸併排序。漫談經典排序演算法 一 從簡單選擇排序到堆排序的深度解析 漫談經典排序演算法 二 各種插入排序解析及效能比較 漫談經典排序演算法 三 氣泡排序 快速排序 漫談經典排序演算法 四 歸併排序 漫談經典排序演算法 五 線性時間排序 計數 基數 桶排序 ...