摘要:穩(wěn)定排序穩(wěn)定排序是指,如果原數(shù)組中有多個(gè)元素是相等的,那么這些元素在排序后數(shù)組的相對(duì)順序應(yīng)該保持不變。實(shí)現(xiàn)歸并排序穩(wěn)定排序。的參數(shù)必須為數(shù)組排序范圍順序已經(jīng)正確歸并排序穩(wěn)定排序。
穩(wěn)定排序
穩(wěn)定排序是指,如果原數(shù)組中有多個(gè)元素是“相等的”,那么這些元素在排序后數(shù)組的相對(duì)順序應(yīng)該保持不變。
比如:我們對(duì){name:string, age:number}[]數(shù)組用age進(jìn)行排序,有很多人是25歲,那么在排序后的數(shù)組中,這些25歲的人應(yīng)該按照它們【在原數(shù)組中出現(xiàn)的順序】來(lái)排列。
原生的sort是不一定是穩(wěn)定的,因?yàn)椴煌囊鎸?shí)現(xiàn)不同,比如V8的sort就用到快排,快排不是穩(wěn)定的排序。
為什么需要穩(wěn)定的排序?其中一種情況是:原列表已經(jīng)在某個(gè)字段上排好序,然而要排序的字段上可能有很多項(xiàng)是“相等”的。
比如有一個(gè){name:string, age:number}[]數(shù)組,它【已經(jīng)在name上按照字母順序排好序】了,現(xiàn)在希望按照age來(lái)排序。假設(shè)有很多人的age是25,如果排序是穩(wěn)定的話,就能保證這些25歲的人【在輸出列表中是按照字母順序排列的】,這樣的話輸出的列表會(huì)好看很多。
/** * @description 歸并排序(穩(wěn)定排序)。 * 此方法會(huì)改變?cè)瓟?shù)組,如果不想破壞原數(shù)組,調(diào)用者自己創(chuàng)建數(shù)組副本作為參數(shù)。 */ function mergeSortJavaScript(arr: T[], compare: (a: T, b: T) => -1 | 0 | 1): T[] { if (!Array.isArray(arr)) { throw new Error("mergeSort的參數(shù)必須為數(shù)組"); } _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; } // 順序已經(jīng)正確 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 歸并排序(穩(wěn)定排序)。 * 此方法會(huì)改變?cè)瓟?shù)組,如果不想破壞原數(shù)組,調(diào)用者自己創(chuàng)建數(shù)組副本作為參數(shù)。 */ function mergeSort(arr, compare) { if (!Array.isArray(arr)) { throw new Error("mergeSort的參數(shù)必須為數(shù)組"); } _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; } // 順序已經(jīng)正確 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); }測(cè)試
去leetcode上找一道能用排序的題測(cè)試,比如75. Sort Colors(雖然說(shuō)這道題不用排序效率更高)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/94411.html
摘要:今天再來(lái)看看另外三種時(shí)間復(fù)雜度都是的排序算法,分別是希爾排序歸并排序和快速排序。三數(shù)取中法求將放到數(shù)組的末尾總結(jié)這三種排序算法的平均時(shí)間復(fù)雜度都是,歸并排序和快速排序的應(yīng)用更廣泛。 1. 回顧 前面說(shuō)完了三種較為簡(jiǎn)單的排序算法,分別是冒泡排序,選擇排序和插入排序,它們的平均情況時(shí)間復(fù)雜度都是 O(n2),比較的高,適合小規(guī)模的數(shù)據(jù)排序,其中插入排序的效率稍高,所以更推薦使用插入排序。今...
摘要:之所以把歸并排序快速排序希爾排序堆排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。歸并排序是一種穩(wěn)定的排序方法。因此,快速排序并不穩(wěn)定。希爾排序思想先將整個(gè)待排序的記錄序列分割成為若干子序列。 showImg(https://segmentfault.com/img/bVbvpYZ?w=900&h=250); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,只有內(nèi)功深厚者,前端之路才...
閱讀 908·2023-04-25 18:51
閱讀 1863·2021-09-09 11:39
閱讀 3276·2019-08-30 15:53
閱讀 2090·2019-08-30 13:03
閱讀 1304·2019-08-29 16:17
閱讀 574·2019-08-29 11:33
閱讀 1878·2019-08-26 14:00
閱讀 2118·2019-08-26 13:41