2016 年底最后一篇,对链表进行插入排序。系列目录见 前言和目录 。javascript
实现一个 insertSort()
函数对链表进行升序排列(插入排序)。实现过程当中可使用 上一个 kata 中的 sortedInsert()
函数。insertSort()
函数接受链表头为参数并返回排序后的链表头。java
var list = 4 -> 3 -> 1 -> 2 -> null insertSort(list) === 1 -> 2 -> 3 -> 4 -> null
若是传入的链表为 null
或者只有一个节点,就原样返回。node
插入排序的介绍能够看 Wikipedia ,大致逻辑为:git
创建一个新的空链表。github
依次遍历待排序的链表节点,挨个插入新链表的合适位置,始终保持新链表是已排序的。算法
遍历完成,返回新链表。编程
观察这段逻辑不难发现,第二个步骤其实就是上个 kata 中 sortedInsert
作的事情 -- 把节点插入一段已排序的链表的合适位置。在此之上稍微包装一下就能够实现 insertSort
。segmentfault
首先咱们记住两个函数的表达的意思:函数
insertSort
返回链表的排序版本。测试
sortedInsert
把节点插入一个已排序链表的合适位置,并返回修改后的链表(也是已排序的)。
而后咱们用递归的思路描述 insertSort
逻辑,应该是先把原链表的第一个节点插入某个已排序的链表的合适位置,这段逻辑能够用 sortedInsert(someList, head.data)
表达。而这个 “某个已排序的链表” ,咱们须要它包含除了 head
以外其余的因此节点,这个链表能够用 insertSort(head.next)
来表达。
整理后的代码以下:
function insertSort(head) { if (!head) return null return sortedInsert(insertSort(head.next), head.data) }
循环版本是最接近算法描述的版本,因此很少赘述。代码以下:
function insertSort(head) { for (var sortedList = null, node = head; node; node = node.next) { sortedList = sortedInsert(sortedList, node.data) } return sortedList }
由于有上个 kata 的函数的帮助,这个插入排序实现起来很是简单。递归版本再次体现了声明式编程的优点。有时候能表达某种数据的不仅是变量,也能够是函数。只要咱们发现表达合适逻辑的函数,实现过程就会很是简单。
算法相关的代码和测试我都放在 GitHub 上,若是对你有帮助请帮我点个赞!