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);
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章