利用遞歸實現鏈表的排序(歸並排序)


利用遞歸實現鏈表的排序(歸並排序)

8c47e58b6247676f3ef14e617a4686bc258cc573e36fcf67c1b0712fa7ed1699-Picture2

利用歸並排序,我們可以將時間復雜度降至O(nlogn), 並且我們是對鏈表進行排序,可以通過修改引用來更改節點順序,無需像數組一樣開辟而外的空間。

利用遞歸實現鏈表的歸並排序有兩個環節:

分割cut環節:

我們可以利用fast, slow快慢雙指針實現鏈表的分割, fast一次移動兩位, slow一次移動一位,當fast移動到末尾時,slow移動到中間位置。

利用變量為tmp = slow.next記錄后鏈表的頭節點,並將slow.next = null將前后鏈表斷開。

ListNode sortList(ListNode head) {
  if (head == null || head.next == null)
    return head;
  
  ListNode fast = head.next, slow = head;
  while (fast != null && fast.next != null) {
    fast = fast.next.next; // 一次移動兩位
    slow = slow.next; // 一次移動一位
  }
  
  ListNode tmp = slow.next; // 記錄后鏈表的頭節點
  slow.next = null; // 將前后鏈表斷開
  //...
}

cut遞歸的終止條件 base case 為當head.next == null,即鏈表只有一個節點。

歸並merge環節:

使用輔助指針,將前后鏈表后合並為一個有序鏈表

ListNode sortList(ListNode head) {
  //...
  // left 為前鏈表的頭節點, right 為后鏈表的頭節點, h 為輔助節點
  while (left != null && right != null) {
    if (left.val < right.val) { 
      h.next = left;
      left = left.next;
    } else {
      h.next = right;
      right = right.next;
    }
    h = h.next;
  }
  h.next = left != null ? left : right;
  //...
}

明白上面的兩個環節后,就能輕松明白我們完整的算法了。

ListNode sortList(ListNode head) {
        if (head == null || head.next ==null)
            return head;
        // cut過程
        ListNode fast = head.next, slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode tmp = slow.next;
        slow.next = null;
	// merage過程
        ListNode left = sortList(head);
        ListNode right = sortList(tmp);
        ListNode h = new ListNode(0);
        ListNode res = h;
        while (left != null && right != null) {
            if (left.val < right.val) {
                h.next = left;
                left = left.next;
            } else {
                h.next = right;
                right = right.next;
            }
            h = h.next;
        }
        h.next = left != null ? left : right;

        return res.next;
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM