一、單向循環鏈表
表中的最后一個節點的指針域指向頭結點,整個鏈表形成一個環。其他的與單鏈表相同。
(以下圖片均來自網絡,侵刪)
插入操作
刪除操作
簡單實現
public class CiNode { private Object data; private CiNode next; private static CiNode first; // 臨時結點,頭結點,並不是鏈表里想要的值,起到標記鏈表頭的作用 public CiNode() { super(); } public CiNode(Object data, CiNode next) { super(); this.data = data; this.next = next; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public CiNode getNext() { return next; } public void setNext(CiNode next) { this.next = next; } public static void add(CiNode node, int index) { if (index == 0) { node.next = first.next; first.next = node; } else { int temp = 0; for (CiNode n = first.next;; n = n.next) { temp++; if (temp == index) { node.next = n.next; n.next = node; break; } } } } public static void remove(int index) { if (index % 5 == 0) { // 刪除第一個元素,考慮循環 first.next = first.next.next; } else { int temp = 0; for (CiNode n = first.next;; n = n.next) { if (n == first) { temp -= 1; // 減一是因為鏈表循環計數時會把first記一次,所以這里減一次,使下標一致 } temp++; if (temp == index) { n.next = n.next.next; break; } } } } public static void display() { for (CiNode n = first.next; n != first; n = n.next) { System.out.print(n.data + " "); } System.out.println(); } public static void main(String[] args) { CiNode node4 = new CiNode("ddd", null); CiNode node3 = new CiNode("ccc", node4); CiNode node2 = new CiNode("bbb", node3); CiNode node1 = new CiNode("aaa", node2); first = new CiNode(null, node1); node4.next = first; System.out.println("當前鏈表:"); display(); add(new CiNode("eee", null), 5); // 傳5進去是為了體現循環,當參數大於了鏈表長度時,又回到first System.out.println("插入后鏈表:"); display(); remove(11); System.out.println("刪除后鏈表:"); display(); } }
循環單鏈表模擬擊鼓傳花游戲
public class JiGuChuanHua implements Runnable { private Object person;//游戲的人的data private JiGuChuanHua next;//指向下一個人, private static JiGuChuanHua first;//第一個人 public JiGuChuanHua() { super(); } //構造方法 public JiGuChuanHua(Object person, JiGuChuanHua next) { super(); this.person = person; this.next = next; } @Override public void run() { JiGuChuanHua loser = first; //以第一個人為起點 double time = (Math.random() + 0.5) * 10; //隨機產生游戲時間(5-15s) boolean flag = true;//結束線程的標志 System.out.println("本局游戲時間:" + time + "s"); System.out.println("游戲開始:"); System.out.println(loser.person);//初始游戲時,花在第一個人手上,打印 double startTime = System.currentTimeMillis();//獲取開始游戲的時間 while (flag) { for (JiGuChuanHua node = first;; node = node.next) { loser = node.next;//loser指向下一個人,模擬傳花過程 System.out.println(loser.person);//打印拿到花的人 try { Thread.sleep((long) (Math.random() * 500));//線程睡眠,模擬花在每一個人手中停留時間 } catch (InterruptedException e) { e.printStackTrace(); } double endTime = System.currentTimeMillis();//傳完一個人時的時間 if (endTime - startTime >= time * 1000) {//游戲時間到,這里不具備原子性,所以是大於等於 flag = false;//標志位置為false break; } } } System.out.println("游戲結束,拿到花的人是:" + loser.person);//打印最后拿到花的人 } public static void main(String[] args) { //將參加游戲的人用鏈表連起來,構成一個循環 JiGuChuanHua person5 = new JiGuChuanHua("e", null); JiGuChuanHua person4 = new JiGuChuanHua("d", person5); JiGuChuanHua person3 = new JiGuChuanHua("c", person4); JiGuChuanHua person2 = new JiGuChuanHua("b", person3); JiGuChuanHua person1 = new JiGuChuanHua("a", person2); person5.next = person1; first = person1; JiGuChuanHua jgch = new JiGuChuanHua(); Thread thread = new Thread(jgch); thread.start(); //開啟線程 } }
二、雙向循環鏈表
從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅結點和后繼結點。一般我們都構造雙向循環鏈表。
插入操作
刪除操作
簡單實現
public class CiDlNode { private Object data; private CiDlNode next; private CiDlNode prev; private static CiDlNode first; public CiDlNode() { super(); } public CiDlNode(Object data, CiDlNode next, CiDlNode prev) { super(); this.data = data; this.next = next; this.prev = prev; } public static void insert(Object data, int index) { CiDlNode node = new CiDlNode(data, null, null); if (index == 0) { node.next = first.next; first.next.prev = node; first.next = node; node.prev = first; } else { int temp = 0; for (CiDlNode n = first.next;; n = n.next) { temp++; if (temp == index) { node.next = n.next; node.next = n.next; n.next.prev = node; n.next = node; node.prev = n; break; } } } } public static void remove(Object data) { for (CiDlNode n = first.next; n != first; n = n.next) { if (n.data.equals(data)) { n.prev.next = n.next; n.next.prev = n; } } } public static void print() { for (CiDlNode node = first.next; node != first; node = node.next) { System.out.print(node.data + " "); } System.out.println(); } public static void main(String[] args) { first = new CiDlNode("0", null, null); CiDlNode node1 = new CiDlNode("aaa", null, first); CiDlNode node2 = new CiDlNode("bbb", null, node1); CiDlNode node3 = new CiDlNode("ccc", null, node2); CiDlNode node4 = new CiDlNode("ddd", first, node3); node3.next = node4; node2.next = node3; node1.next = node2; first.next = node1; System.out.println("當前鏈表:"); print(); insert("ddd", 5); System.out.println("插入后鏈表:"); print(); remove("ddd"); System.out.println("刪除后鏈表:"); print(); } }