鏈表的基本操做,刪除插入。

lass Node {
    int val;    // data | element
    Node next;  // 若是 next == null 表示是最後一個結點

    Node(int val) {
        this.val = val;
        this.next = null;
    }

    public String toString() {
        return String.format("Node(%d)", val);
    }
}

public class MyLinkedList {
    public static void main(String[] args) {
        Node head = null;
        // head 的意思是鏈表的第一個結點
        // 經過第一個結點,就能夠找到完整的鏈表的全部結點
        // 因此,鏈表的第一個結點每每表明整個鏈表

        // 空的鏈表,就是一個結點都沒有的鏈表
        // 也就沒有第一個結點
        // head == null 表示第一個結點不存在
        // 也就是整個鏈表爲空

        // 頭插
        /*
        int val = 0;
        // 1. 結點
        Node node = new Node(val);
        // 2. 讓原來的 head 成爲 node 的下一個結點
        node.next = head;
        // 3. 更新第一個結點的引用
        head = node;

        pushFront(head, 0);
        */

        head = pushFront(head, 0);
        head = pushFront(head, 1);
        head = pushFront(head, 2);

        // 打印
        print(head);    // 2 1 0

        // 尾插
        head = popFront(head);
        print(head);    // 1 0

        head = pushBack(head, 10);
        head = pushBack(head, 20);
        head = pushBack(head, 30);
        print(head);    // 1 0 10 20 30
        head = popBack(head);
        head = popBack(head);
        head = popBack(head);
        head = popBack(head);
        head = popBack(head);

        head = popBack(head);   // 報錯
        print(head);        // 空

        head = pushBack(head, 100);
        print(head);        // 100
    }

    // 打印
    private static void print(Node head) {
        System.out.println("打印鏈表:");
        for (Node cur = head; cur != null; cur = cur.next) {
            System.out.print(cur + " --> ");
        }
        System.out.println("null");
    }

    // 頭插
    // head: 原來的第一個結點
    // val:要插入的值
    // 返回:新的第一個結點
    private static Node pushFront(Node head, int val) {
        // 1. 結點
        Node node = new Node(val);
        // 2. 讓原來的 head 成爲 node 的下一個結點
        node.next = head;
        // 3. 更新第一個結點的引用
        return node;
    }

    private static Node pushBack(Node head, int val) {
        Node node = new Node(val);
        if (head == null) {//能夠在null前插,不能再null後插,這個判頭結點null
            return node;
        } else {
            Node last = head;
            while (last.next != null) {
                last = last.next;
            }
            last.next = node;

            return head;
        }
    }

    private static Node popFront(Node head) {
        if (head == null) {
            System.err.println("空鏈表沒法刪除");
            return null;
        }

        // 原來第一個結點,會由於沒有引用指向而被回收
        return head.next;
    }

    private static Node popBack(Node head) {
        if (head == null) {//只要刪除都要判null  
            System.err.println("空鏈表沒法刪除");
            return null;
        }

        if (head.next == null) {//尾刪判斷只有一個,
            return null;
        } else {
            Node lastSecond = head;//刪除最後一個,先找到倒數第二個,讓倒數第二個的下一個爲null
            while (lastSecond.next.next != null) {
                lastSecond = lastSecond.next;
            }

            lastSecond.next = null;
            return head;
        }
    }
}
相關文章
相關標籤/搜索