www.cnblogs.com/ericz2j/p/1…
一、单向循环链表
表中的最后一个节点的指针域指向头结点,整个链表形成一个环。其他的与单链表相同。
(以下图片均来自网络,侵删)

插入操作

删除操作

简单实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 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进去是为了体现循环,当参数大于了链表长度时,又回到firstSystem.out.println("插入后链表:");display();remove(11);System.out.println("删除后链表:");display();}} |
循环单链表模拟击鼓传花游戏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | public class JiGuChuanHua implements Runnable {private Object person;//游戏的人的dataprivate JiGuChuanHua next;//指向下一个人,private static JiGuChuanHua first;//第一个人public JiGuChuanHua() {super();}//构造方法public JiGuChuanHua(Object person, JiGuChuanHua next) {super();this.person = person;this.next = next;}@Overridepublic 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;//标志位置为falsebreak;}}}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(); //开启线程}} |
二、双向循环链表
从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

插入操作

删除操作

简单实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 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();}} |