1. 程式人生 > >【劍指Offer學習】【面試題13 :在O(1)時間刪除連結串列結點】

【劍指Offer學習】【面試題13 :在O(1)時間刪除連結串列結點】


程式碼實現:

public class Test13 {
    /**
     * 連結串列結點
     */
    public static class ListNode {
        int value; // 儲存連結串列的值
        ListNode next; // 下一個結點
    }

    /**
     * 給定單向連結串列的頭指標和一個結點指標,定義一個函式在0(1)時間刪除該結點,
     * 【注意1:這個方法和文字上的不一樣,書上的沒有返回值,這個因為JAVA引用傳遞的原因,
     * 如果刪除的結點是頭結點,如果不採用返回值的方式,那麼頭結點永遠刪除不了】
     * 【注意2:輸入的待刪除結點必須是待連結串列中的結點,否則會引起錯誤,這個條件由使用者進行保證】
     *
     * @param head        連結串列表的頭
     * @param toBeDeleted 待刪除的結點
     * @return 刪除後的頭結點
     */
    public static ListNode deleteNode(ListNode head, ListNode toBeDeleted) {

        // 如果輸入引數有空值就返回表頭結點
        if (head == null || toBeDeleted == null) {
            return head;
        }

        // 如果刪除的是頭結點,直接返回頭結點的下一個結點
        if (head == toBeDeleted) {
            return head.next;
        }

        // 下面的情況連結串列至少有兩個結點

        // 在多個節點的情況下,如果刪除的是最後一個元素
        if (toBeDeleted.next == null) {
            // 找待刪除元素的前驅
            ListNode tmp = head;
            while (tmp.next != toBeDeleted) {
                tmp = tmp.next;
            }
            // 刪除待結點
            tmp.next = null;

        }
        // 在多個節點的情況下,如果刪除的是某個中間結點
        else {
            // 將下一個結點的值輸入當前待刪除的結點
            toBeDeleted.value = toBeDeleted.next.value;
            // 待刪除的結點的下一個指向原先待刪除引號的下下個結點,即將待刪除的下一個結點刪除
            toBeDeleted.next = toBeDeleted.next.next;
        }

        // 返回刪除節點後的連結串列頭結點
        return head;
    }

    /**
     * 輸出連結串列的元素值
     *
     * @param head 連結串列的頭結點
     */
    public static void printList(ListNode head) {
        while (head != null) {
            System.out.print(head.value + "->");
            head = head.next;
        }
        System.out.println("null");
    }

    public static void main(String[] args) {


        ListNode head = new ListNode();
        head.value = 1;

        head.next = new ListNode();
        head.next.value = 2;

        head.next.next = new ListNode();
        head.next.next.value = 3;

        head.next.next.next = new ListNode();
        head.next.next.next.value = 4;

        ListNode middle = head.next.next.next.next = new ListNode();
        head.next.next.next.next.value = 5;

        head.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.value = 6;

        head.next.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.next.value = 7;

        head.next.next.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.next.next.value = 8;

        ListNode last = head.next.next.next.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.next.next.next.value = 9;

        head = deleteNode(head, null); // 刪除的結點為空
        printList(head);
        ListNode node = new ListNode();
        node.value = 12;

        head = deleteNode(head, head); // 刪除頭結點
        printList(head);
        head = deleteNode(head, last); // 刪除尾結點
        printList(head);
        head = deleteNode(head, middle); // 刪除中間結點
        printList(head);

        head = deleteNode(head, node); // 刪除的結點不在連結串列中
        printList(head);
    }
}

執行結果: