148. 排序链表 归并排序 | 快速排序

148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

输入: 4->2->1->3
输出: 1->2->3->4

来源:https://leetcode-cn.com/problems/sort-list/

归并排序法:

  1. 利用快慢指针将链表分为前后半段
  2. 先对slow.next找到后半段并进行排序
  3. 断开链表前后半段,对前半段进行排序
  4. 合并排序完成后的左右两条链表
function mergeTwoLists(x, y) {
    if (!x || !y)
        return x ? x : y;
    let p = new ListNode(-1);
    let root = p;
    while (x && y) {
        if (x.val < y.val) {
            p.next = x;
            x = x.next;
        } else {
            p.next = y;
            y = y.next;
        }
        p = p.next;
    }
    /* 连接剩余部分 */
    p.next = x ? x : y;
    return root.next;
}
function mergeSort(root) {
    /* 数量不到2个直接返回 */
    if (!root || !root.next) return root;
    /* 快慢指针找出中间点 */
    let slow = root, fast = root.next.next;
    while (fast && fast.next) {
        slow = slow.next;
        fast = fast.next.next;
    }
    /* 对右半部分进行归并 */
    let right = mergeSort(slow.next);
    /* 断开左右连接 */
    slow.next = null;
    /* 左半部分归并 */
    let left = mergeSort(root);
    /* 合并左右 */
    return mergeTwoLists(left, right);
}
var sortList = function (head) {
    return mergeSort(head);
};

快速排序法:

  1. 设置头尾指针,将第一个结点的值作为参考值,
  2. 遍历后面的元素,将小于参考值的节点抽离到临时链表
  3. 此时原链表全为大于等于参考值的元素,且第一个值为参考值,临时链表全为小于参考值的元素,将原链表接到临时链表后面即将参考节点放到了最终的位置
  4. 覆盖原链表,对参考值左边和右边元素进行相同的操作
/* 对(st,ed)区间的元素进行排序 */
function quickSort(st, ed) {
    /* 至少存在一个值 */
    if (st == ed || st.next == ed) return st;
    /* x为遍历指针 p为参考值 */
    let x = st.next, p = st.next;
    /* 临时链表存小于p的所有元素 */
    let tpSt = new ListNode(-1);
    let tp = tpSt;
    /* 遍历(st,ed)区间 */
    while (x.next != ed) {
        /* 当前值小于p则抽离到临时链表 */
        if (x.next.val < p.val) {
            tp.next = x.next;
            tp = tp.next;
            /* 原链表删除 */
            x.next = x.next.next;
        } else { x = x.next; }
    }
    /* 原链表全大于p 临时链表全小于p*/
    tp.next = st.next;
    st.next = tpSt.next;
    quickSort(st, p);
    quickSort(p, ed);
    return st.next;
}
var sortList = function (head) {
    if (!head || !head.next)
        return head;
    let newHead = new ListNode(-1);
    newHead.next = head;
    return quickSort(newHead, null);
};
posted @ 2020-05-11 12:13  aeipyuan  阅读(141)  评论(0编辑  收藏  举报