摘要:穩定排序穩定排序是指,如果原數組中有多個元素是相等的,那么這些元素在排序后數組的相對順序應該保持不變。實現歸并排序穩定排序。的參數必須為數組排序范圍順序已經正確歸并排序穩定排序。
穩定排序
穩定排序是指,如果原數組中有多個元素是“相等的”,那么這些元素在排序后數組的相對順序應該保持不變。
比如:我們對{name:string, age:number}[]數組用age進行排序,有很多人是25歲,那么在排序后的數組中,這些25歲的人應該按照它們【在原數組中出現的順序】來排列。
原生的sort是不一定是穩定的,因為不同的引擎實現不同,比如V8的sort就用到快排,快排不是穩定的排序。
為什么需要穩定的排序?其中一種情況是:原列表已經在某個字段上排好序,然而要排序的字段上可能有很多項是“相等”的。
比如有一個{name:string, age:number}[]數組,它【已經在name上按照字母順序排好序】了,現在希望按照age來排序。假設有很多人的age是25,如果排序是穩定的話,就能保證這些25歲的人【在輸出列表中是按照字母順序排列的】,這樣的話輸出的列表會好看很多。
/** * @description 歸并排序(穩定排序)。 * 此方法會改變原數組,如果不想破壞原數組,調用者自己創建數組副本作為參數。 */ function mergeSortJavaScript(arr: T[], compare: (a: T, b: T) => -1 | 0 | 1): T[] { if (!Array.isArray(arr)) { throw new Error("mergeSort的參數必須為數組"); } _ms(arr, compare, 0, arr.length); return arr; } /** * @description 排序范圍:[begin, end) */ function _ms (arr: T[], compare: (a: T, b: T) => -1 | 0 | 1, begin: number, end: number): void { const size = end - begin; if (size <= 1) { return; } // tslint:disable-next-line: no-bitwise const middle = (end + begin) >> 1; _ms(arr, compare, begin, middle); _ms(arr, compare, middle, end); if (compare(arr[middle - 1], arr[middle]) <= 0) { return; } // 順序已經正確 const merged = []; let leftIndex = begin, rightIndex = middle; while (merged.length < size) { if (leftIndex === middle) { merged.push(arr[rightIndex++]); } else if (rightIndex === end) { merged.push(arr[leftIndex++]); } else { const c = compare(arr[leftIndex], arr[rightIndex]); if (c <= 0) { merged.push(arr[leftIndex++]); } else { merged.push(arr[rightIndex++]); } } } arr.splice(begin, size, ...merged); }
/** * @description 歸并排序(穩定排序)。 * 此方法會改變原數組,如果不想破壞原數組,調用者自己創建數組副本作為參數。 */ function mergeSort(arr, compare) { if (!Array.isArray(arr)) { throw new Error("mergeSort的參數必須為數組"); } _ms(arr, compare, 0, arr.length); return arr; } /** * @description 排序范圍:[begin, end) */ function _ms(arr, compare, begin, end) { var size = end - begin; if (size <= 1) { return; } // tslint:disable-next-line: no-bitwise var middle = (end + begin) >> 1; _ms(arr, compare, begin, middle); _ms(arr, compare, middle, end); if (compare(arr[middle - 1], arr[middle]) <= 0) { return; } // 順序已經正確 var merged = []; var leftIndex = begin, rightIndex = middle; while (merged.length < size) { if (leftIndex === middle) { merged.push(arr[rightIndex++]); } else if (rightIndex === end) { merged.push(arr[leftIndex++]); } else { var c = compare(arr[leftIndex], arr[rightIndex]); if (c <= 0) { merged.push(arr[leftIndex++]); } else { merged.push(arr[rightIndex++]); } } } arr.splice(begin, size, ...merged); }測試
去leetcode上找一道能用排序的題測試,比如75. Sort Colors(雖然說這道題不用排序效率更高)。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/94411.html
摘要:今天再來看看另外三種時間復雜度都是的排序算法,分別是希爾排序歸并排序和快速排序。三數取中法求將放到數組的末尾總結這三種排序算法的平均時間復雜度都是,歸并排序和快速排序的應用更廣泛。 1. 回顧 前面說完了三種較為簡單的排序算法,分別是冒泡排序,選擇排序和插入排序,它們的平均情況時間復雜度都是 O(n2),比較的高,適合小規模的數據排序,其中插入排序的效率稍高,所以更推薦使用插入排序。今...
摘要:之所以把歸并排序快速排序希爾排序堆排序放在一起比較,是因為它們的平均時間復雜度都為。歸并排序是一種穩定的排序方法。因此,快速排序并不穩定。希爾排序思想先將整個待排序的記錄序列分割成為若干子序列。 showImg(https://segmentfault.com/img/bVbvpYZ?w=900&h=250); 1. 前言 算法為王。 想學好前端,先練好內功,只有內功深厚者,前端之路才...
閱讀 917·2023-04-25 18:51
閱讀 1870·2021-09-09 11:39
閱讀 3283·2019-08-30 15:53
閱讀 2099·2019-08-30 13:03
閱讀 1310·2019-08-29 16:17
閱讀 582·2019-08-29 11:33
閱讀 1884·2019-08-26 14:00
閱讀 2124·2019-08-26 13:41