1. 程式人生 > >循環控制-鏈表刪除結點

循環控制-鏈表刪除結點

給定 增加 recursion integer str view 刪除 ESS process

0.目錄

1.刪除結點的思路

2.Java代碼實現

  • 2.1 鏈表刪除結點的實現
  • 2.2 頭結點怎麽辦
  • 2.3 測試用例

1.刪除結點的思路

鏈表刪除結點的意思就是給定一個值,把鏈表中與給定值相等的結點全部刪除:
例如1 → 2 → 3 → 2 → 5 → Null,刪除給定值2,變為:1 → 3 → 5 → Null

刪除的思路:
技術分享圖片
用一個previous指針指向3,如果3的下一個元素是2,就讓3指向5(相當於跳過了2),而previous依舊指向3。

PS:本篇結點和創建鏈表的實現同前文 遞歸控制-創建鏈表

2.Java代碼實現

2.1 鏈表刪除結點的實現

不考慮頭結點時的實現:

    public Node deleteIfEquals(Node head, int value) {
        Node prev = head;
        // Loop invariant: list nodes from head up to prev has been processed.
        // (Nodes with values equal to value are deleted.)
        while (prev.getNext() != null) {
            if (prev.getNext().getValue() == value) {
                // delete it
                prev.setNext(prev.getNext().getNext());
            } else {
                prev = prev.getNext();
            }
        }

        return head;
    }

2.2 頭結點怎麽辦

頭結點沒有previous怎麽辦?

  1. 特殊處理
  2. 增加虛擬頭結點

此處采用特殊處理頭結點(在Node prev = head;前面加上以下代碼):

        if (head == null) {
            return null;
        }

        if (head.getValue() == value) {
            head = head.getNext();
        }

但是程序依然有問題,比如說2 → 2 → 3 → 2 → 5 → Null,這樣開頭有兩個2,執行以上程序後只會刪除第一個2。
優化一下:

        if (head == null) {
            return null;
        }

        while (head.getValue() == value) {
            head = head.getNext();
        }

會發現程序依然有問題,比如說2 → 2 → 2 → 2 → 2 → Null,這樣全是2,執行以上程序後head就是null了。這樣在while循環中程序會執行null.getValue(),自然會報錯。
再優化一下:

        if (head == null) {
            return null;
        }

        while (head != null && head.getValue() == value) {
            head = head.getNext();
        }

運行程序會看到依然有問題,比如說2 → 2 → 2 → 2 → 2 → Null,這樣全是2,執行以上程序後head就是null了。這樣在接下來的程序中會執行null.getNext(),自然會報錯。
再優化一下:

        while (head != null && head.getValue() == value) {
            head = head.getNext();
        }

        if (head == null) {
            return null;
        }

最終的刪除節點實現:

    public Node deleteIfEquals(Node head, int value) {
        while (head != null && head.getValue() == value) {
            head = head.getNext();
        }

        if (head == null) {
            return null;
        }

        Node prev = head;
        // Loop invariant: list nodes from head up to prev has been processed.
        // (Nodes with values equal to value are deleted.)
        while (prev.getNext() != null) {
            if (prev.getNext().getValue() == value) {
                // delete it
                prev.setNext(prev.getNext().getNext());
            } else {
                prev = prev.getNext();
            }
        }

        return head;
    }

2.3 測試用例

測試程序是否正確運行:

    public static void main(String[] args) {
        LinkedListCreator creator = new LinkedListCreator();
        LinkedListDeletor deletor = new LinkedListDeletor();
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(1, 2, 3, 2, 5)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 2, 3, 2, 2)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 2, 2, 2, 2)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(1)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(new ArrayList<Integer>()), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 3, 4, 5, 2)), 2));
    }

運行結果為
技術分享圖片

main所在java文件全部代碼:

import interview.common.Node;
import interview.recursion.LinkedListCreator;

import java.util.ArrayList;
import java.util.Arrays;

public class LinkedListDeletor {

    public Node deleteIfEquals(Node head, int value) {
        while (head != null && head.getValue() == value) {
            head = head.getNext();
        }

        if (head == null) {
            return null;
        }

        Node prev = head;
        // Loop invariant: list nodes from head up to prev has been processed.
        // (Nodes with values equal to value are deleted.)
        while (prev.getNext() != null) {
            if (prev.getNext().getValue() == value) {
                // delete it
                prev.setNext(prev.getNext().getNext());
            } else {
                prev = prev.getNext();
            }
        }

        return head;
    }

    public static void main(String[] args) {
        LinkedListCreator creator = new LinkedListCreator();
        LinkedListDeletor deletor = new LinkedListDeletor();
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(1, 2, 3, 2, 5)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 2, 3, 2, 2)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 2, 2, 2, 2)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(1)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2)), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(new ArrayList<Integer>()), 2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 3, 4, 5, 2)), 2));
    }
}

循環控制-鏈表刪除結點