用 JavaScript 实现链表操作 - 15 Merge Sort

TL;DR

对链表进行归并排序,系列目录见 前言和目录

需求

实现函数 mergeSort() 进行归并排序。注意这种排序法需要使用递归。在 frontBackSplit()sortedMerge() 两个函数的帮助下,你可以很轻松的写一个递归的排序。基本算法是,把一个链表切分成两个更小的链表,递归地对它们进行排序,最终把两个排好序的小链表合成完整的链表。

var list = 4 -> 2 -> 1 -> 3 -> 8 -> 9 -> null
mergeSort(list) === 1 -> 2 -> 3 -> 4 -> 8 -> 9 -> null

解法

归并排序的运行方式是,递归的把一个大链表切分成两个小链表。切分到最后就全是单节点链表了,而单节点链表可以被认为是已经排好序的。这时候再两两合并,最终会得到一个完整的已排序链表。

因为切分和合并两个最重要的功能都已经实现,需要思考的就只是如何递归整个过程了。我们分析一下可以把整个过程分成:

  1. frontBackSplit() 把链表切分成两个,分别叫 firstsecond

  2. firstsecond 排序。

  3. sortedMerge() 把排好序的两个链表合并起来。

其中第 2 步就是递归的点,因为排序这个事情恰好是 mergeSort 本身可以做的。

代码如下:

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))
}

参考资料

Codewars Kata
GitHub 的代码实现
GitHub 的测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值