您好,登錄后才能下訂單哦!
小編給大家分享一下JavaScript如何實(shí)現(xiàn)歸并排序,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
javascript欄目在本文中,我們學(xué)習(xí) Merge Sort 背后的邏輯,并用 JavaScript 實(shí)現(xiàn)。最后,在空間和時(shí)間復(fù)雜度方面將歸并排序與其他算法進(jìn)行比較。
歸并排序背后的邏輯
歸并排序使用分而治之的概念對(duì)給定的元素列表進(jìn)行排序。它將問(wèn)題分解為較小的子問(wèn)題,直到它們變得足夠簡(jiǎn)單以至可以直接解決為止。
以下是歸并排序的步驟:
將給定的列表分為兩半(如果列表中的元素?cái)?shù)為奇數(shù),則使其大致相等)。
以相同的方式繼續(xù)劃分子數(shù)組,直到只剩下單個(gè)元素?cái)?shù)組。
從單個(gè)元素?cái)?shù)組開(kāi)始,合并子數(shù)組,以便對(duì)每個(gè)合并的子數(shù)組進(jìn)行排序。
重復(fù)第 3 步單元,直到最后得到一個(gè)排好序的數(shù)組。
以數(shù)組 [4, 8, 7, 2, 11, 1, 3]
為例,讓我們看一下歸并排序是如何工作的:
用 JavaScript 實(shí)現(xiàn)歸并排序
首先實(shí)現(xiàn)一個(gè)將兩個(gè)已排序子數(shù)組合并為一個(gè)已排序數(shù)組的函數(shù) merge()
。要注意著兩個(gè)子數(shù)組是已經(jīng)被排好序的,這一點(diǎn)非常重要, merge()
函數(shù)只用于其進(jìn)行合并。
可以通過(guò)遍歷這兩個(gè)子數(shù)組來(lái)實(shí)現(xiàn):
function merge(left, right) { let arr = [] // 如果任何一個(gè)數(shù)組為空,就退出循環(huán) while (left.length && right.length) { // 從左右子數(shù)組的最小元素中選擇較小的元素 if (left[0] < right[0]) { arr.push(left.shift()) } else { arr.push(right.shift()) } } // 連接剩余的元素,防止沒(méi)有把兩個(gè)數(shù)組遍歷完整 return [ ...arr, ...left, ...right ] }
在這個(gè)函數(shù)中,通過(guò)把兩個(gè)排好序的子數(shù)組(left
、right
)合并來(lái)獲得一個(gè)排好序的大數(shù)組。首先,創(chuàng)建一個(gè)空數(shù)組。之后在 left
和 right
兩個(gè)子數(shù)組中最小元素中的較小的一個(gè),并將其添加到空數(shù)組。我們只需要檢查 left
和 right
子數(shù)組中的第一個(gè)元素,因?yàn)樗鼈兪且雅藕眯虻摹?/p>
在這個(gè)過(guò)程中,從子數(shù)組中刪除了被選擇的元素(通過(guò) shift()
函數(shù)實(shí)現(xiàn))。繼續(xù)這個(gè)過(guò)程,直到其中一個(gè)子數(shù)組變?yōu)榭铡W詈蟀逊强兆訑?shù)組的剩余元素(因?yàn)樗鼈円呀?jīng)被排序)插入主數(shù)組的最后面。
現(xiàn)在有了合并兩個(gè)已排序數(shù)組的代碼,接下來(lái)為實(shí)現(xiàn)歸并排序算法的最終代碼。這意味著要繼續(xù)分割數(shù)組,直到最終只包含一個(gè)元素的數(shù)組為止:
function mergeSort(array) { const half = array.length / 2 if(array.length < 2){ return array } const left = array.splice(0, half) return merge(mergeSort(left),mergeSort(array)) }
在代碼中先確定中點(diǎn),并用 splice()
函數(shù)將數(shù)組分為兩個(gè)子數(shù)組。如果元素?cái)?shù)量為奇數(shù),則左側(cè)的元素?cái)?shù)量會(huì)少一個(gè)。不斷的劃分?jǐn)?shù)組,直到剩下單個(gè)元素的數(shù)組(array.length < 2
)。然后用之前實(shí)現(xiàn)的 merge()
函數(shù)合并子數(shù)組。
代碼實(shí)現(xiàn)后用前面的用例測(cè)試一下:
array = [4, 8, 7, 2, 11, 1, 3]; console.log(mergeSort(array));
輸出符合預(yù)期:
1,2,3,4,7,8,11
歸并排序的效率
歸并排序的最差時(shí)間復(fù)雜度為 $O(n\\log n)$,與快速排序的最佳情時(shí)間復(fù)雜度相同。歸并排序是目前最快的排序算法之一。
與快速排序不同,歸并排序不是in-place排序算法,這意味著除了輸入數(shù)組之外,它還會(huì)占用額外的空間。這是因?yàn)槲覀兪褂昧溯o助數(shù)組來(lái)存儲(chǔ)子數(shù)組。歸并排序的空間復(fù)雜度為 $O(n)$。
歸并排序的另一個(gè)優(yōu)點(diǎn)是非常適合多線程,因?yàn)槊總€(gè)被劃分出的一半都可以單獨(dú)排序。另一種常見(jiàn)的減少歸并排序運(yùn)行時(shí)間的方法是在到達(dá)相對(duì)較小的子數(shù)組時(shí)(大約 7 個(gè)元素)使用插入排序。這是因?yàn)椴迦肱判蛟谔幚硇⌒突驇缀跖藕眯虻臄?shù)組時(shí)表現(xiàn)非常好。
看完了這篇文章,相信你對(duì)“JavaScript如何實(shí)現(xiàn)歸并排序”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。