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

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

說明:如下代碼是按照本身理解實現,有不正確的地方,請批評指正!!算法

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;
    }

}
相關文章
相關標籤/搜索