一、单向循环链表
表中的最后一个节点的指针域指向头结点,整个链表形成一个环。其他的与单链表相同。

(以下图片均来自网络,侵删)

插入操作

删除操作

简单实现

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

Java数据结构——循环链表的更多相关文章

  1. Java数据结构——循环链表的实现

    //单链表结点类 public class Node<T> { //单链表结点类,T指定结点的元素类型 public T data; //数据域,保存数据元素 public Node< ...

  2. java与数据结构(3)---java实现循环链表

    循环链表:将单链表中尾结点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种首尾相接的单链表称为单链表循环表,即循环链表. 循环链表与单链表最重要的区别是:尾结点的指针,不再是p->n ...

  3. Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用

    Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...

  4. Java数据结构之线性表(2)

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  5. Java数据结构之线性表

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  6. Java数据结构和算法(一)线性结构

    Java数据结构和算法(一)线性结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 线性表 是一种逻辑结构,相同数据类型的 ...

  7. JAVA数据结构系列 栈

    java数据结构系列之栈 手写栈 1.利用链表做出栈,因为栈的特殊,插入删除操作都是在栈顶进行,链表不用担心栈的长度,所以链表再合适不过了,非常好用,不过它在插入和删除元素的时候,速度比数组栈慢,因为 ...

  8. Java数据结构之树和二叉树(2)

    从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...

  9. Java数据结构之树和二叉树

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

随机推荐

  1. jenkins初学部分笔记网站

    https://www.cnblogs.com/wfd360/p/11314697.html 自动化部署详细教程 https://blog.csdn.net/weixin_41948075/artic ...

  2. 渲染导航菜单的同时给每个菜单绑定不同的router跳转

    这个问题一开始的时候,我总想着router跳转只有两种方式 一种@click,一种router-link 然后我想着@click,绑定一个事件,事件下面无法确定我当前是哪个菜单,解决不了. 然后< ...

  3. 将形如 5D, 30s 的字符串转为秒

    import sys def convert_to_seconds(time_str): # write code here if 's' in time_str: return float(time ...

  4. C++ 第三天 Vector、函数

    1.Vector vector是一个动态增长的数组,它会随着我们添加的内容,会逐步的增加空间.实际上它并不是在原来的地方追加空间,而是开辟新的空间,然后把原来的数据都拷贝到新的空间里面去,接着让容器指 ...

  5. 11-21 logging 模块

    默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志, 这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ER ...

  6. PHP readfile() 函数

    定义和用法 readfile() 函数读取一个文件,并写入到输出缓冲. 如果成功,该函数返回从文件中读入的字节数.如果失败,该函数返回 FALSE 并附带错误信息.您可以通过在函数名前面添加一个 '@ ...

  7. Android MTK平台 客制化系统来电界面(屏蔽 InCallUI 提供接口给客户自行展示来电去电页面)

    OS: Android 8.1 需求分析 1.禁止系统来电铃声,提供接口给客户自己播放铃声 2.禁止系统拉起来去电页面(InCallActivity),消息通知客户拉起自己的来去电页面 3.禁止来电消 ...

  8. Ajax 提交图片

    话不多说,直接上代码 页面部分 <form id="form1" enctype="multipart/form-data"> id_token: ...

  9. map,reduce和filter函数

    numArray = [1, 2, 3, 4, 5] def ercifang(x): return x ** 2 def map_test(func, numArray): li = [] for ...

  10. Linux系统中玩到让你停不下来的命令行游戏!

    大家好,我是良许. 在使用 Linux 系统时,命令行不仅可以让我们在工作中提高效率,它还可以在生活上给我们提供各种娱乐活动,因为你可以使用它玩许多非常有意思的游戏,这些游戏可都不需要使用专用显卡. ...