Java實現鏈表的增加,刪除,打印


Java中我們使用的ArrayList,其實現原理是數組。而LinkedList的實現原理就是鏈表了。鏈表在進行循環遍歷時效率不高,但是插入和刪除時優勢明顯。

說明:以下代碼是按照自己理解實現,有不正確的地方,請批評指正!!

1. 定義結點類

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

2. 建表(尾插法)

思路:
頭插法建立鏈表雖然算法簡單,但生成的鏈表中結點的次序和輸入的順序相反。若希望二者次序一致,可采用尾插法建表。該方法是將新結點插入到當前鏈表的表尾上,為此必須增加一個尾指針tail,使其始終指向當前鏈表的尾結點。
// 1. 創建單鏈表(尾插法建表)
    public static ListNode createList(int[] arr)
    {
        ListNode head = new ListNode(arr[0]); // 頭結點
        ListNode tail = head;
        for (int i = 1; i < arr.length; i++)
        {
            ListNode newNode = new ListNode(arr[i]);
            tail.next = newNode;
            tail = newNode;
        }
        return head;
    }

3. 打印鏈表

// 2. 打印鏈表
    public static void printList(ListNode head)
    {
        while (head != null)
        {
            if (head.next == null)
                System.out.println(head.val);
            else
                System.out.print(head.val + " --> ");

            head = head.next;
        }
    }
// 輸出結果: 11 --> 22 --> 33 --> 44 --> 55

4. 插入結點

	// 3. 在建好的鏈表中的第k個位置插入一個值為val的結點
   public static ListNode insertNode(ListNode head, int k, int val)
    {
        ListNode preNode = head; // 臨時指針,用於指向要插入位置的前一個結點

        if (k < 1)
            return head;
        if (k == 1) // 如果在第一個位置插入(將插在第1個結點之前)
        {
            ListNode newNode = new ListNode(val); // 創建該結點
            newNode.next = preNode;
            head = newNode;

            return head;
        }

        while (k-- > 2) // 使preNode指向第k個位置的前一個結點
        {
            preNode = preNode.next;
        }

        ListNode newNode = new ListNode(val); // 創建該新結點
        // 插入
        newNode.next = preNode.next;
        preNode.next = newNode;

        return head;
    }

5. 刪除結點

// 4. 刪除結點(刪除第k個結點)
 public static ListNode delNode(ListNode head, int k)
    {
        ListNode preNode = head; // 臨時指針,用於指向要刪除位置的前一個結點

        if (k < 1) // 不刪任何結點
            return head;
        if (k == 1) // 刪除第一個結點
        {
            head = head.next; // 將指針往后移動一位就相當於刪除了第一個結點
            return head;
        }

        while (k-- > 2) // 使preNode指向第k個結點的前面一個結點
        {
            preNode = preNode.next;
        }
        // 刪除結點(通過跳過待刪除結點來實現刪除結點的效果)
        preNode.next = preNode.next.next;

        return head;
    }

6. 總代碼

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

public class Main {
    public static void main(String[] args) {

        int[] arr = {11, 22, 33, 44, 55};
        ListNode head = createList(arr); // 建表

        // 打印鏈表
        printList(head);

        // 插入
//        //head = insertNode(head, 1, 99); // 在第一個位置插入99
//        head = insertNode(head, 3, 99);  // 在第3個位置插入99
//        printList(head);

        // 刪除
        head = delNode(head, 2);  // 刪除地2個結點
        printList(head);


    }

    // 1. 創建帶頭結點的單鏈表(尾插法建表)
    public static ListNode createList(int[] arr)
    {
        ListNode head = new ListNode(arr[0]); // 頭結點
        ListNode tail = head;
        for (int i = 1; i < arr.length; i++)
        {
            ListNode newNode = new ListNode(arr[i]);
            tail.next = newNode;
            tail = newNode;
        }
        return head;
    }

    // 2. 打印鏈表
    public static void printList(ListNode head)
    {
        while (head != null)
        {
            if (head.next == null)
                System.out.println(head.val);
            else
                System.out.print(head.val + " --> ");

            head = head.next;
        }
    }


    // 3. 在建好的鏈表中的第k個位置插入一個值為val的結點
    public static ListNode insertNode(ListNode head, int k, int val)
    {
        ListNode preNode = head; // 臨時指針,用於指向要插入位置的前一個結點

        if (k < 1)
            return head;
        if (k == 1) // 如果在第一個位置插入(將插在第1個結點之前)
        {
            ListNode newNode = new ListNode(val); // 創建該結點
            newNode.next = preNode;
            head = newNode;

            return head;
        }

        while (k-- > 2) // 使preNode指向第k個位置的前一個結點
        {
            preNode = preNode.next;
        }

        ListNode newNode = new ListNode(val); // 創建該新結點
        // 插入
        newNode.next = preNode.next;
        preNode.next = newNode;

        return head;
    }


    // 4. 刪除結點(刪除第k個結點)
    public static ListNode delNode(ListNode head, int k)
    {
        ListNode preNode = head; // 臨時指針,用於指向要刪除位置的前一個結點

        if (k < 1) // 不刪任何結點
            return head;
        if (k == 1) // 刪除第一個結點
        {
            head = head.next; // 將指針往后移動一位就相當於刪除了第一個結點
            return head;
        }

        while (k-- > 2) // 使preNode指向第k個結點的前面一個結點
        {
            preNode = preNode.next;
        }
        // 刪除結點(通過跳過待刪除結點來實現刪除結點的效果)
        preNode.next = preNode.next.next;

        return head;
    }

}


免責聲明!

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



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