Java中咱們使用的ArrayList,其實現原理是數組。而LinkedList的實現原理就是鏈表了。鏈表在進行循環遍歷時效率不高,可是插入和刪除時優點明顯。java
說明:如下代碼是按照本身理解實現,有不正確的地方,請批評指正!!算法
class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }
思路: 頭插法創建鏈表雖然算法簡單,但生成的鏈表中結點的次序和輸入的順序相反。若但願兩者次序一致,可採用尾插法建表。該方法是將新結點插入到當前鏈表的表尾上,爲此必須增長一個尾指針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; }
// 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
// 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; }
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; } }