Java数据结构——循环链表
一、单向循环链表
表中的最后一个节点的指针域指向头结点,整个链表形成一个环。其他的与单链表相同。
(以下图片均来自网络,侵删)

插入操作

删除操作

简单实现
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数据结构——循环链表的更多相关文章
- Java数据结构——循环链表的实现
//单链表结点类 public class Node<T> { //单链表结点类,T指定结点的元素类型 public T data; //数据域,保存数据元素 public Node< ...
- java与数据结构(3)---java实现循环链表
循环链表:将单链表中尾结点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种首尾相接的单链表称为单链表循环表,即循环链表. 循环链表与单链表最重要的区别是:尾结点的指针,不再是p->n ...
- Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用
Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...
- Java数据结构之线性表(2)
从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...
- Java数据结构之线性表
从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...
- Java数据结构和算法(一)线性结构
Java数据结构和算法(一)线性结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 线性表 是一种逻辑结构,相同数据类型的 ...
- JAVA数据结构系列 栈
java数据结构系列之栈 手写栈 1.利用链表做出栈,因为栈的特殊,插入删除操作都是在栈顶进行,链表不用担心栈的长度,所以链表再合适不过了,非常好用,不过它在插入和删除元素的时候,速度比数组栈慢,因为 ...
- Java数据结构之树和二叉树(2)
从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...
- Java数据结构之树和二叉树
从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...
随机推荐
- 集合的一些实例的demo实现
按照斗地主的规则,完成洗牌发牌的动作. 具体规则: 使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌. 准备牌: 牌可以设计为一个ArrayList,每个字符串为一 ...
- Maven中出现Could not find artifact ...:pom:0.0.1-SNAPSHOT
参考链接:https://blog.csdn.net/zpwggi123/article/details/87189959 多模块项目构建时,先将总项目install,之后子项目分别install,注 ...
- PHP 太空船运算符(组合比较符)
PHP 7 新增加的太空船运算符(组合比较符)用于比较两个表达式 $a 和 $b,如果 $a 小于.等于或大于 $b时,它分别返回-1.0或1. 实例 <?php // 整型比较 print( ...
- C 语言学习 -1
头文件 stdio.h stdlib.h sting.h 先学习上面三个头文件: 1: stdio.h 这个头文件包含了 程序与外界数据交互的各种函数 说白了就是 用来处理 输入/输 ...
- [NOI2012]随机数生成器【矩阵快速幂】
NOI2012 随机数生成器 题目描述 栋栋最近迷上了随机算法,而随机数是生成随机算法的基础.栋栋准备使用线性同余法(Linear Congruential Method)来生成一个随机数列,这种方法 ...
- 简单配置iOS的通用链接,迅速解决“universal link 校验不通过”问题!
对于需要使用微信支付等功能的APP来说,对接微信提供的openSDK是不可缺少的一环.随着苹果iOS 13系统版本的安全升级,为此openSDK在1.8.6版本进行了适配.1.8.6之后的openSD ...
- (转)交叉编译lrzsz
交叉编译lrzsz 2016-03-20 1. 系统环境: Distributor ID: Ubuntu Description: Ubuntu 14.04.1 LTS Release: ...
- 全球疫情爬取APP版
全球疫情统计APP图表展示: 将该任务分解成三部分来逐个实现: ①爬取全球的疫情数据存储到云服务器的MySQL上 ②在web项目里添加一个servlet,通过参数的传递得到对应的json数据 ③设计A ...
- 再见,付费录屏软件!我用70行Python代码打造免费版!
- spring data jpa 之 通用接口
园主这一阵子接到一个需求,就是将spring data jpa再进行封装,实现通过调用一个baseRepository,来实现每个类的增删改查操作,结合spring data jpa 原有的便捷操作, ...