對鏈表進行歸併排序,系列目錄見 前言和目錄 。git
實現函數 mergeSort()
進行歸併排序。注意這種排序法須要使用遞歸。在 frontBackSplit() 和 sortedMerge() 兩個函數的幫助下,你能夠很輕鬆的寫一個遞歸的排序。基本算法是,把一個鏈表切分紅兩個更小的鏈表,遞歸地對它們進行排序,最終把兩個排好序的小鏈表合成完整的鏈表。github
var list = 4 -> 2 -> 1 -> 3 -> 8 -> 9 -> null mergeSort(list) === 1 -> 2 -> 3 -> 4 -> 8 -> 9 -> null
歸併排序的運行方式是,遞歸的把一個大鏈表切分紅兩個小鏈表。切分到最後就全是單節點鏈表了,而單節點鏈表能夠被認爲是已經排好序的。這時候再兩兩合併,最終會獲得一個完整的已排序鏈表。算法
由於切分和合並兩個最重要的功能都已經實現,須要思考的就只是如何遞歸整個過程了。咱們分析一下能夠把整個過程分紅:segmentfault
用 frontBackSplit()
把鏈表切分紅兩個,分別叫 first
和 second
。函數
對 first
和 second
排序。測試
用 sortedMerge()
把排好序的兩個鏈表合併起來。ui
其中第 2 步就是遞歸的點,由於排序這個事情剛好是 mergeSort
自己能夠作的。code
代碼以下:排序
const { Node } = require('./00-utils') const { frontBackSplit } = require('./12-front-back-split') const { sortedMerge } = require('./14-sorted-merge') function mergeSort(list) { if (!list || !list.next) return list const first = new Node() const second = new Node() frontBackSplit(list, first, second) return sortedMerge(mergeSort(first), mergeSort(second)) }