排序算法-歸并排序

一、原理解析

歸并排序不像前面講過(guò)的幾個(gè)排序那樣直觀卸亮,為了便于理解忽妒,我們先做個(gè)問(wèn)題分解。

假設(shè)有兩個(gè)已經(jīng)排序好的數(shù)組:

let arrLeft = [1, 3, 4, 7]
let arrRight = [2, 5, 6, 9]
如何把這兩個(gè)已排序好的數(shù)組合并成一個(gè)排序好的數(shù)組呢?

可以新建一個(gè)空數(shù)組arrResult锰扶,比較arrLeft 第一位和 arrRight 第一位献酗,哪個(gè)小就把這個(gè)數(shù)組的第一位拿出來(lái)push到空數(shù)組里。然后反復(fù)執(zhí)行上面的邏輯坷牛,直到arrLeft或者arrRight其中一個(gè)變?yōu)榭諗?shù)組罕偎。最后再把另一個(gè)不為空的全部拿出來(lái) push 到arrResult。 以下是代碼:

function merge(leftArr, rightArr) {
    var resultArr = []
    while(leftArr.length && rightArr.length) {
      resultArr.push(leftArr[0] <= rightArr[0] ? leftArr.shift() : rightArr.shift())
    }
    return resultArr.concat(leftArr).concat(rightArr)
  }

那回頭看看我們要真實(shí)解決的問(wèn)題京闰,如何對(duì)一個(gè)未排序的數(shù)組進(jìn)行排序呢颜及?

對(duì)于如下數(shù)組:

let arr = [4, 1, 2, 6, 9, 7, 3, 5]
我們可以把數(shù)組分成兩部分:

let part1 = [4, 1, 2, 6]
let part2 = [9, 7, 3, 5]
假設(shè)我們已經(jīng)寫(xiě)好了我們最終要實(shí)現(xiàn)的排序方法 mergeSort。那么 mergeSort(arr) 等價(jià)于merge(mergeSort(part1), mergeSort(part2)) 蹂楣。 即:對(duì)數(shù)組 arr 的排序俏站,等價(jià)于把數(shù)組分兩部分分別對(duì)每部分排序得到兩個(gè)排序的數(shù)組,然后再利用剛剛寫(xiě)好的merge 方法把兩個(gè)已經(jīng)排序好的數(shù)組合并成一個(gè)最終排序好的數(shù)組痊土。

那mergeSort(part1) 的結(jié)果又怎么計(jì)算呢肄扎?繼續(xù)遵循上面的邏輯,對(duì) part1繼續(xù)分解赁酝,直到分解為對(duì)長(zhǎng)度為1的數(shù)組進(jìn)行排序(直接返回即可)犯祠。

function mergeSort() {
  //待補(bǔ)充
}

mergeSort(arr) 
//等價(jià)于
merge(mergeSort(part1), mergeSort(part2))

總結(jié):要排序一個(gè)大數(shù)組,可以把這個(gè)大數(shù)組拆分成兩個(gè)小數(shù)組酌呆,把問(wèn)題轉(zhuǎn)變成分別排序這兩個(gè)小數(shù)組衡载,再把排序后的兩個(gè)小數(shù)組通過(guò)簡(jiǎn)單的處理方式“歸并為”最終需要的結(jié)果。 如何排序這兩個(gè)小數(shù)組呢隙袁?循環(huán)剛剛的邏輯痰娱,直到數(shù)組拆分到極小(數(shù)組長(zhǎng)度為1菩收,排序的結(jié)果就是自己)梨睁。

二、代碼實(shí)現(xiàn)

以下是 JavaScript 版本的的代碼實(shí)現(xiàn):

function mergeSort(arr) {
  var merge = function(leftArr, rightArr) {
    var resultArr = []
    while(leftArr.length && rightArr.length) {
      resultArr.push(leftArr[0] <= rightArr[0] ? leftArr.shift() : rightArr.shift())
    }
    return resultArr.concat(leftArr).concat(rightArr)
  }
  if(arr.length < 2) return arr
  let mid = arr.length >> 1  //取數(shù)組的中位下標(biāo)娜饵,也可以用 parseInt(arr.length/2)
  return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)))
}

三而姐、復(fù)雜度

平均時(shí)間復(fù)雜度為 O(nlogn),性能極好划咐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拴念,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子褐缠,更是在濱河造成了極大的恐慌政鼠,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件队魏,死亡現(xiàn)場(chǎng)離奇詭異公般,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瞬雹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)酗捌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涌哲,“玉大人阀圾,你說(shuō)我怎么就攤上這事∥姓妫” “怎么了肾筐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵局齿,是天一觀的道長(zhǎng)抓歼。 經(jīng)常有香客問(wèn)我拢锹,道長(zhǎng),這世上最難降的妖魔是什么蹋半? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任减江,我火速辦了婚禮捻爷,結(jié)果婚禮上也榄,老公的妹妹穿的比我還像新娘。我一直安慰自己降宅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著唠雕,像睡著了一般岩睁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冰啃,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天阎毅,我揣著相機(jī)與錄音扇调,去河邊找鬼抢肛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛熬芜,可吹牛的內(nèi)容都是我干的涎拉。 我是一名探鬼主播的圆,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毁枯!你這毒婦竟也來(lái)了叮称?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤娱节,失蹤者是張志新(化名)和其女友劉穎祭示,沒(méi)想到半個(gè)月后质涛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年阅羹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捏鱼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酪耕。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡看尼,死狀恐怖婚被,靈堂內(nèi)的尸體忽然破棺而出梳虽,到底是詐尸還是另有隱情窜觉,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站描孟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏场航。R本人自食惡果不足惜廉羔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一孩饼、第九天 我趴在偏房一處隱蔽的房頂上張望竹挡。 院中可真熱鬧,春花似錦汽畴、人聲如沸耸序。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)男应。三九已至,卻和暖如春游桩,著一層夾襖步出監(jiān)牢的瞬間借卧,已是汗流浹背筛峭。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工影晓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锌订。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓辆飘,卻偏偏與公主長(zhǎng)得像蜈项,于是被迫代替她去往敵國(guó)和親紧卒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诗祸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 快排和歸并排序的思想都是分治 歸并排序 整體而已搓谆,歸并排序比插入排序更優(yōu)但近乎有序的數(shù)組,歸并排序還是比插入排序慢...
    青春豬頭少年_閱讀 551評(píng)論 0 1
  • 歸并排序 原理 歸并排序思想 該算法采用經(jīng)典的分治(divide-and-conquer)策略(分治法將問(wèn)題分(d...
    GoFuncChan閱讀 528評(píng)論 0 1
  • 歸并排序 思路:使用分治思想颤诀,將數(shù)組一直拆分着绊,直到拆分成一個(gè)元素熟尉,此時(shí)每一個(gè)元素都相當(dāng)于一個(gè)有序的數(shù)組斤儿,之后再將每...
    守敬閱讀 493評(píng)論 0 1
  • 總結(jié) 歸并排序主要用了分治的思想,通過(guò)將數(shù)組分成較小的段一铅,對(duì)小段進(jìn)行排序然后將小段合并起來(lái)潘飘,從而完成排序卜录。歸并排序...
    Hurtck閱讀 207評(píng)論 0 0
  • 二路歸并排序主旨是“分解”與“歸并” 分解: 1.將一個(gè)數(shù)組分成兩個(gè)數(shù)組,分別對(duì)兩個(gè)數(shù)組進(jìn)行排序搜囱。 2.循環(huán)第一步...
    Jorunk閱讀 287評(píng)論 0 0