循環鏈表(單鏈表)
當循環鏈表中只有一個節點時,節點自己指向自己。實現循環鏈表,需要一個外部變量指向鏈表的尾節點。
class CircleLinkedList<T> { private class Node { T data; Node next; Node(T data) { this.data = data; } } private Node last; }
向鏈表中插入元素有三種情況,插入到鏈表的頭部,插入到鏈表的尾部,插入到鏈表兩個節點之間。當然,無論是哪種情況,都要檢查鏈表是否為空。如果鏈表為空,讓last指向新創建的節點,并自己指向自己。
private void addToEmpty(T data) { var newNode = new Node(data); last = newNode; newNode.next =last; // 鏈表自己指向自己 }
如果鏈表不為空,比如有如下鏈表

1,向鏈表頭部插入元素,比如向鏈表的頭部插入6,那就先創建一個新節點newNode, 然后讓newNode.next 指向last.next,因為last.next就是頭節點,最后讓last.next指向最新的頭節點newNode.

public void addFront(T data) { if (last == null) { addToEmpty(data); } else { var newNode = new Node(data); newNode.next = last.next; last.next = newNode; } }
2,向鏈表尾部插入節點,讓last的next指向新的節點,last再指向新節點,當然,不要忘記它是循環鏈表,新節點的next還要指向頭節點

public void addLast(T data) { if (last == null) { addToEmpty(data); } else { var newNode = new Node(data); newEntry.next = last.next; // 新節點的next指向頭節點 last.next = newEntry; last = newEntry; } }
3,向兩個節點之間添加元素,就是向某一個元素后面添加元素,首先遍歷鏈表,找到這個元素。如果這個元素正好是尾節點,那么還要移動last的位置

// 向某個item后面 添加值, public void addAfter(T item, T data) { if(last == null) { throw new RuntimeException("鏈表為空"); } else { var found = false; var temp = last.next; // 頭節點 do { if(temp.data.equals(item)){ found = true; } else { temp = temp.next; } } while(temp != last.next && !found); if(found) { // temp就是將要向它向面添加元素的節點 var newNode = new Node(data); // 先獲取到舊的temp.next var oldNext = temp.next; temp.next = newNode; newNode.next = oldNext; //如果正好添加尾節點后面,還要移動last的指向 if (temp == last) { last = newNode; } } else { throw new RuntimeException("沒有找到元素"); } } }
刪除節點:如果鏈表為空,肯定是要報錯的。如果鏈表中只有一個節點,那么如果刪除的節點正好是這個節點,那么就刪除,last=null,如果不是,那也只能報錯了。如果有多個節點,但正好刪除的是最后一個節點,那就要循環鏈表,找到最后一個節點的前一個節點,然后修改last指向,

如果是刪除中間一個元素,遍歷找到前一個節點,

public void deleteNode(T item) { // 鏈表為空,肯定不能刪除 if(last == null) { throw new RuntimeException("鏈表為空"); } else if(last.next == last) { // 鏈表只有一個節點 if (last.data.equals(item)){ last = null; } else { throw new RuntimeException("沒有找到元素"); } // 鏈表有多個節點 } else if (last.data.equals(item)) { // 刪除的節點,正好是最后一個節點 // 找到最后一個節點的前一個節點 var temp = last; while(temp.next != last) { temp = temp.next; } temp.next = last.next; last = temp; } else { var temp = last; // 找到前面一個節點 while(!temp.next.data.equals(item) && temp.next != last) { temp = temp.next; } if(temp.next.data.equals(item)) { temp.next= temp.next.next; } else { throw new RuntimeException("沒有找到元素"); } } }
遍歷
public void traverse() { if (last == null) { throw new RuntimeExceiption('空鏈表'); } var p = last.next; do { System.out.print(p.data + " "); p = p.next; } while (p != last.next); }
測試
public static void main(String[] args) { var circleList = new CircleSingleLinkedList<Integer>(); circleList.addFront(6); circleList.addEnd(8); circleList.addFront(2); circleList.addAfter(2, 10); circleList.traverse(); System.out.println(); circleList.deleteNode(8); circleList.traverse(); }

浙公網安備 33010602011771號