【Algorithm】連結串列演算法中啞結點作用

TypantK發表於2019-03-14

題目描述

Sort a linked list using insertion sort.


一般思路(直接在原連結串列上進行插排)

很好理解,就是遍歷每個結點cur,同時記錄其前一個結點pre。

如果碰到某個cur的值小於pre,從頭結點開始遍歷,直到找到應該插入的位置。

不使用啞結點的問題就是多判斷了一個cur要替換頭結點,頭結點往後移的狀況,這時不能用遍歷的程式碼

需要額外寫一種情況

                if(head.val > cur.val){
                    cur.next = head;
                    head = cur;
                }

 

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public static ListNode insertionSortList(ListNode head) {
        if(head == null || head.next == null)return head;
        for(ListNode pre = head; pre.next != null; ){
            ListNode cur = pre.next;
            if(cur.val < pre.val){    
                pre.next = cur.next;
                ListNode p = head;
                ListNode c = p.next;
                if(head.val > cur.val){
                    cur.next = head;
                    head = cur;
                }else {
                	//將cur從head遍歷到其應該插入的地方(大於前者p小於後者c.next)
                    while(c != cur && c != null){
                        //頭結點額外判斷

                        if(c.val > cur.val){
                            p.next = cur;
                            cur.next = c;
                            break;
                        }
                        p = c;
                        c = c.next;
                    }
                }
            }else pre = pre.next;
        }
        return head;
    }
}

 

使用啞結點

大致思路其實是一致的,但是他新建了一個啞結點作為“新的連結串列”(其實就建了一個結點)。

這樣就不可能有替換頭結點的情況了,因為頭結點的值為Integer.MIN_VALUE。

*和啞結點沒關係的地方:查詢插入位置的時候用的是pre.next,而不是像上面維護兩個指標p/h來查詢插入位置。

**也就是pre代表了p,pre.next代表了h,verygood

    public static ListNode insertionSortList(ListNode head) {
       
        //啞結點
        ListNode dummy = new ListNode(Integer.MIN_VALUE);
        ListNode pre = dummy;
        ListNode cur = head;
        while(cur != null){
            ListNode next = cur.next;
            pre = dummy;
            
            while(pre.next != null && pre.next.val < cur.val){
                pre = pre.next;
            }
            cur.next = pre.next;
            pre.next = cur;
            
            cur = next;
            
        }
        return dummy.next;
    }
}

 

相關文章