题目
给你链表的头结点
head,请将其按 升序 排列并返回 排序后的链表 。
输入: head = [4,2,1,3]
输出: [1,2,3,4]
题解
我们首先在sortList函数中先定义一个虚拟节点dummy,将其next指向头节点head,方便操作链表,在使用getLength函数获取链表长度len,然后使用步长step进行循环排序,每次将链表分成长度为step的两个子链表,然后将这两个子链表合并成一个有序链表,最后将所有的有序子链表合并成一个有序链表,在定义pre和cur两个指针,这两个指针分别指向虚拟节点dummy和头节点head,然后循环链表,将链表分成长度为step的两个子链表,接下来使用split函数将链表分成长度为step的两个子链表h1和h2,在使用split函数将链表再次分成长度为step的两个子链表,cur指针指向第二个子链表的头节点,最后使用merge函数将两个子链表h1和h2合并成一个有序链表,pre.next指向合并后的链表,使用循环将链表排序完成,最后返回虚拟节点dummy的next节点即为排序后的链表,上述的操作时将链表进行递归分成两个子链表,分别对子链表进行排序,然后将两个有序子链表合并成一个有序链表进行返回了出来
var sortList = function (head) {
const dummy = new ListNode(-1)
const len = getLength(head)
dummy.next = head;
for (let step = 1; step < len; step = step * 2) {
let pre = dummy, cur = dummy.next
while (cur) {
let h1 = cur
let h2 = split(h1, step)
cur = split(h2, step)
pre.next = merge(h1, h2)
while (pre.next) {
pre = pre.next
}
}
}
return dummy.next
function getLength(head) {
let i = 0
while (head) {
i++
head = head.next
}
return i
}
function merge(l1, l2) {
let head = new ListNode(-1), pre = head
while (l1 && l2) {
if (l1.val < l2.val) {
pre.next = l1
l1 = l1.next
} else {
pre.next = l2
l2 = l2.next
}
pre = pre.next
}
pre.next = l1 ? l1 : l2
return head.next
}
function split(head, step) {
if (head == null) return null
let pre = head, next = null
for (let i = 1; i < step && pre.next; i++) {
pre = pre.next
}
next = pre.next
pre.next = null
return next
}
};
坚持努力,无惧未来!