W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
「歸并排序 merge sort」是一種基于分治策略的排序算法,包含圖 11-10 所示的“劃分”和“合并”階段。
圖 11-10 歸并排序的劃分與合并階段
如圖 11-11 所示,“劃分階段”從頂至底遞歸地將數(shù)組從中點(diǎn)切分為兩個(gè)子數(shù)組。
mid
? ,遞歸劃分左子數(shù)組(區(qū)間 ?[left, mid]
? )和右子數(shù)組(區(qū)間 ?[mid + 1, right]
? )。“合并階段”從底至頂?shù)貙⒆笞訑?shù)組和右子數(shù)組合并為一個(gè)有序數(shù)組。需要注意的是,從長(zhǎng)度為 1 的子數(shù)組開(kāi)始合并,合并階段中的每個(gè)子數(shù)組都是有序的。
圖 11-11 歸并排序步驟
觀察發(fā)現(xiàn),歸并排序與二叉樹(shù)后序遍歷的遞歸順序是一致的。
merge_sort.cpp
/* 合并左子數(shù)組和右子數(shù)組 */
// 左子數(shù)組區(qū)間 [left, mid]
// 右子數(shù)組區(qū)間 [mid + 1, right]
void merge(vector<int> &nums, int left, int mid, int right) {
// 初始化輔助數(shù)組
vector<int> tmp(nums.begin() + left, nums.begin() + right + 1);
// 左子數(shù)組的起始索引和結(jié)束索引
int leftStart = left - left, leftEnd = mid - left;
// 右子數(shù)組的起始索引和結(jié)束索引
int rightStart = mid + 1 - left, rightEnd = right - left;
// i, j 分別指向左子數(shù)組、右子數(shù)組的首元素
int i = leftStart, j = rightStart;
// 通過(guò)覆蓋原數(shù)組 nums 來(lái)合并左子數(shù)組和右子數(shù)組
for (int k = left; k <= right; k++) {
// 若“左子數(shù)組已全部合并完”,則選取右子數(shù)組元素,并且 j++
if (i > leftEnd)
nums[k] = tmp[j++];
// 否則,若“右子數(shù)組已全部合并完”或“左子數(shù)組元素 <= 右子數(shù)組元素”,則選取左子數(shù)組元素,并且 i++
else if (j > rightEnd || tmp[i] <= tmp[j])
nums[k] = tmp[i++];
// 否則,若“左右子數(shù)組都未全部合并完”且“左子數(shù)組元素 > 右子數(shù)組元素”,則選取右子數(shù)組元素,并且 j++
else
nums[k] = tmp[j++];
}
}
/* 歸并排序 */
void mergeSort(vector<int> &nums, int left, int right) {
// 終止條件
if (left >= right)
return; // 當(dāng)子數(shù)組長(zhǎng)度為 1 時(shí)終止遞歸
// 劃分階段
int mid = (left + right) / 2; // 計(jì)算中點(diǎn)
mergeSort(nums, left, mid); // 遞歸左子數(shù)組
mergeSort(nums, mid + 1, right); // 遞歸右子數(shù)組
// 合并階段
merge(nums, left, mid, right);
}
實(shí)現(xiàn)合并函數(shù) merge() 存在以下難點(diǎn)。
對(duì)于鏈表,歸并排序相較于其他排序算法具有顯著優(yōu)勢(shì),可以將鏈表排序任務(wù)的空間復(fù)雜度優(yōu)化至 O(1) 。
具體實(shí)現(xiàn)細(xì)節(jié)比較復(fù)雜,有興趣的同學(xué)可以查閱相關(guān)資料進(jìn)行學(xué)習(xí)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: