题目描述
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
输入: head = [4,2,1,3]
输出: [1,2,3,4]
示例 2:
输入: head = [-1,5,3,4,0]
输出: [-1,0,3,4,5]
示例 3:
输入: head = []
输出: []
解题思路1-快速排序
- 先找到当前链表的中间值,把链表分割成两部分,小于中间值的放到h1,大于中间值的放到h2.
- 递归上述步骤,返回排序好的h1和h2
- 将h1链接到h2后面,返回h1即可
代码1
var sortList = function(head) {
// 特判
if(head == null) return head;
let l = head.val, r = head.val, mid;
let p = head, q, h1 = null, h2 = null;
while(p) {
q = p.next;
l = Math.min(p.val, l);
r = Math.max(p.val, r);
p = q;
}
// 当head只有一个值的时候,返回head
if(l == r) return head;
mid = (l + r) / 2; // 找到中间值
p = head;
while(p) {
q = p.next;
if(p.val <= mid) {
p.next = h1;
h1 = p;
} else {
p.next = h2;
h2 = p;
}
p = q;
}
h1 = sortList(h1);
h2 = sortList(h2);
p = h1;
// 循环p.next
while(p.next) {
p = p.next;
}
p.next = h2;
return h1;
}
解题思路2
- 切断所有的链表
- 用sort对切断的链表做排序
- 链接链表
代码2
var sortList = function(head) {
// 特判
if(head == null) return head;
let p = head, q;
let s = [];
while(p) {
q = p.next;
p.next = null;
s.push(p);
p = q;
}
s = s.sort((a, b) => a.val - b.val);
for(let i = 0; i < s.length - 1; i++){
s[i].next = s[i + 1];
}
return s[0];
}
解题思路3-归并排序
- 把链表一分为二,先处理左边,然后处理右边
- 然后分别处理左右两边
代码3
var sortList = function(head) {
let n = 0;
let p = head;
while(p) p = p.next, n += 1;
return mergeSort(head, n);
}
var mergeSort = function(head, n) {
if(head == null || head.next == null) return head;
let l = n >> 2, r = n - l;
let lp = head, rp = lp, p;
for(let i = 1; i < l; i++){
rp = rp.next;
};
p = rp, rp = rp.next;
p.next = null;
lp = mergeSort(lp, l);
rp = mergeSort(rp, r);
let ret = new ListNode();
p = ret;
while(lp || rp) {
if((rp == null) || (lp && lp.val <= rp.val)){
p.next = lp;
lp = lp.next;
p = p.next;
} else {
p.next = rp;
rp = rp.next;
p = p.next;
}
}
return ret.next;
}