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

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

插入操作

删除操作

简单实现

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. PHP array_keys() 函数

    实例 返回包含数组中所有键名的一个新数组: <?php$a=array("Volvo"=>"XC90","BMW"=>&q ...

  2. PHP array_rand() 函数

    实例 返回一个包含随机键名的数组: <?php $a=array("red","green","blue","yellow& ...

  3. PHP floatval()、doubleval () 函数

    floatval 函数用于获取变量的浮点值. floatval 不能用于数组或对象.高佣联盟 www.cgewang.com 版本要求:PHP 4 >= 4.2.0, PHP 5, PHP 7. ...

  4. PHP imagecolorallocatealpha - 为一幅图像分配颜色和透明度

    imagecolorallocatealpha — 为一幅图像分配颜色和透明度.高佣联盟 www.cgewang.com 语法 int imagecolorallocatealpha ( resour ...

  5. 利用mvc模式,实现用户的注册

    实现功能:利用mvc模式,实现用户的登陆注册功能 1.程序的框架结构 2个包,bean,以及servlet 3个jsp页面,注册页面,注册成功页面,注册失败页面 mysql驱动 2.编程思想 通过js ...

  6. WPF桌面程序在请求接口时如何防止被常用的抓包软件Fiddler抓包

    问题:在我开发了一个WPF桌面应用程序的时候,由于涉及到登录等等操作通过Fiddler可以很直观的看到账号密码.首先问题有两点:1.数据提交的时候对于密码等重要的数据没有进行加密操作.2.没有防止抓包 ...

  7. CSS高级特效(下)

    3.混合模式与合成 在图形编辑软件(比如Photoshop)中,设计师很早就可以选择两个设计元素叠加时的颜色如何混合了. CSS Compositing and Blending标准使我们可以在CSS ...

  8. 创建shell脚本文件

    简单来说脚本就是将需要执行的命令保存到文本中,按照顺序(由上往下执行),它是解释型的,不需要 编译 脚本格式 #!/bin/bash或者#!/bin/env bash开头 第一个shell脚本:hel ...

  9. 开发读取.properties 配置文件工具类PropertiesUtil

    import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.juni ...

  10. JS 与 jQery 的区别主要在于 DOM

    //目前正在学习前端阶段,把知识点整理.保存下来以便日后查看 首先引入jQery: 需要先引入css,再引入js: jQery需要在js前引入,再引入框架,最后才是js的引入:css也相同,先引入框架 ...