循环链表是与单链表一样,是一种链式的存储结构,所不同的是,循环链表的最后一个结点的指针是指向该循环链表的第一个结点或者表头结点,从而构成一个环形的链。
循环链表的运算与单链表的运算基本一致。所不同的有以下几点:
1、在建立一个循环链表时,必须使其最后一个结点的指针指向表头结点,而不是象单链表那样置为NULL。此种情况还使用于在最后一个结点后插入一个新的结点。
2、在判断是否到表尾时,是判断该结点链域的值是否是表头结点,当链域值等于表头指针时,说明已到表尾。而非象单链表那样判断链域值是否为NULL。
代码:
public class CircularLinkedList< E> {
private Node< E> head;
private int length; //the length of the list
public CircularLinkedList() {
head = new Node< E>(null, head);
length = 0;
}
public void insertAtPrior(E item) {//在头节点之后加一个节点
Node< E> node = new Node< E>(item, null); //encpsule the item to an node
node.setNext(head.getNext()); //node.next = head.next
head.setNext(node); //head.next = node
length ++;
}
public void add(E item) {//在最后节点上添加一个节点
Node< E> tmp = head;
if (isEmpty()) { // if the list is null
Node< E> node = new Node< E>(item, head); // .. if next == null ?
head.setNext(node);
} else {
Node< E> node = new Node< E>(item, head);
// find the end node of the list
while (head != tmp.getNext()) {
tmp = tmp.getNext();
}
tmp.setNext(node);
}
length++;
}
public E get(int index) { //获取索引处的节点的数据
// 先判断索引正确性
if (index >length || index < 0) {
throw new RuntimeException("索引值有错:" + index);
}else if(isEmpty()){
return null;
}else{
Node< E> tmp =head;
int i= 1;
while (head != tmp.getNext() && i <= index) {
tmp = tmp.getNext();
i++;
}
E e = tmp.getData();
return e;
}
}
public void insert(int index, E item) {//在索引处后添加节点
Node< E> node = new Node< E>(item, null);
Node< E> tmp = head;
int i = 1;
if (index > length || index < 0) {
System.out.println("the index is out of bounds");
} else if (0 == length && 1 == index) {
node.setNext(head);
head.setNext(node);
length++;
} else {
//find the node index
while (head != tmp.getNext() && i <= index) {
tmp = tmp.getNext();
i++;
}
node.setNext(tmp.getNext());
tmp.setNext(node);
length++;
}
}
public void removeFromFront() {//删除头节点之后的第一个节点
Node< E> tmp = head;
if (length < 1) {
System.out.println("The list is null and you can not delete any node!");
} else if (1 == length) {
head.setNext(head);
length--;
} else {
head.setNext(tmp.getNext().getNext());
length--;
}
}
public void remove(int index) {//删除索引处的节点
if (length < 1 || index > length) {
System.out.println("index is out of bounds");
} else if (1 == length && 1 == index) {
head.setNext(head);
length--;
} else {
Node< E> tmp = head;
int i = 1;
//get the node before index
while (head != tmp.getNext() && i < index) {
tmp = tmp.getNext();
i++;
}
tmp.setNext(tmp.getNext().getNext());
length--;
}
}
public void removeFromLast() {//删除最后一个节点
if (length < 1) { // if the list is null
System.out.println("The list is null and you can not delete");
} else if (1 == length) {
head.setNext(head);
length--;
} else {
Node< E> tmp1 = head;
Node< E> tmp2 = head.getNext(); //set tmp2 -tmp1 = 1
while (head != tmp2.getNext()) {
tmp2 = tmp2.getNext();
tmp1 = tmp1.getNext();
}
tmp1.setNext(head);
length--;
}
}
public int getLength() {
return length;
}
public boolean isEmpty() {
return length==0;
}
public void display() {
if (length < 1) {
System.out.println("The list is null");
} else {
Node< E> tmp = head;
while (head != tmp.getNext()) {
tmp = tmp.getNext();
System.out.print(tmp.getData() + " ");
}
}
}
//test the list
public static void main(String[] args) {
CircularLinkedList< Integer> l = new CircularLinkedList< Integer>();
System.out.println(l.isEmpty());
l.add(1);
l.add(2);
l.insertAtPrior(3);
l.insert(2, 4);
l.add(5);
System.out.println("the list is : ");
l.display();
System.out.println();
System.out.println("the length is :" + l.getLength());
l.removeFromFront();
l.removeFromLast();
l.display();
// System.out.println(l.get(3));
}
}
public class Node< E> {
private Node< E> next;
private E data;
public Node(E data) {
this.data = data;
next = null;
}
public Node(E data, Node< E> nextNode) {
this.data = data;
next = nextNode;
}
public void setData(E data) {
this.data = data;
}
public void setNext(Node< E> next) {
this.next = next;
}
public E getData() {
return data;
}
public Node< E> getNext() {
return next;
}
}
分享到:
相关推荐
在提供的文件信息中,虽然标题和描述部分未给出具体内容,但是“java 版本循环链表”的标题和部分描述内容暗示了文章内容应该是与Java编程语言实现的循环链表数据结构相关。循环链表是一种常见的数据结构,在计算机...
循环链表 实现约瑟夫环 java 自己写的 测试通过 有注释
用Java定义一个循环链表,实现链表的基本操作: 初始化*、获取头结点、添加新元素*、删除链表元素 、获取链表元素*、查找链表元素*、更新链表中某个元素、 判断链表是否为空、求链表元素个数、输出链表元素、清空...
列举了java中双向循环列表的各个主要类的代码以及迭代器构造方法。
约瑟夫环,用循环链表实现,语言为Java。假设数到三的数出列。程序输出1到10的出列顺序。
总之,循环链表在Java中的实现涉及节点类的设计和链表类的操作方法。理解并掌握循环链表的特性对于解决一些特定问题,如判断链表是否有环、高效地遍历数据等,是非常重要的。通过阅读和实践提供的`LinkedList.java`...
有序链表合并算法是计算机科学中的一个重要概念,特别是在数据结构和算法分析中。这个算法的主要目的是将两个或多个已排序的链表合并成一个单一的、有序的链表。在本毕业设计中,该算法被动态地演示,使得学生能够更...
在Java中实现循环链表,我们需要定义一个节点类(Node)来存储数据和指向下一个节点的引用,同时在链表类(CircularLinkedList)中维护头节点和当前大小。以下是实现的关键点: 1. **节点类(Node)**:创建一个内部...
总结起来,Java中的循环链表提供了高效的数据存储和访问机制,特别是在需要快速插入和删除元素,且元素数量不确定的情况下。循环链表的特性使得遍历整个列表更加方便,因为最后一个节点指向了第一个节点,避免了特殊...
在Java编程中,我们可以使用面向对象的设计思想来实现循环双链表。通常,这样的数据结构会包含三个主要部分:一个接口定义链表的基本操作,一个类实现这个接口来构建具体的链表结构,还有一个测试类用于验证链表功能...
本话题主要关注的是Java中的链表实现,特别是循环链表的模板类设计。循环链表与普通链表的主要区别在于最后一个节点指向了头节点,形成一个闭合的环,这在处理循环遍历或某些特定算法时非常方便。 首先,让我们详细...
由于在项目中需要用到循环链表,然而在JDK没有其实现,所以用Java语言实现了循环链表,供大家学习和参考。若有任何问题请发送E-Mail:wn_lut@126.com,以交流及改进。 Package:com.utilities.structs 打开方式:...
下面我们将详细讨论循环链表的基本概念,以及如何使用C、C++和JAVA三种语言来实现它。 ### 循环链表基本概念 1. **节点结构**:每个链表节点包含两部分,数据域存储实际数据,指针域存储指向下一个节点的指针。在...
JAVA实现链表_双向链表
在这个压缩包文件“单向循环链表.zip”中,包含了两个源代码文件——LoopSingle.java和List.java,它们分别对应了单向循环链表的节点类和接口定义。 首先,我们来看`LoopSingle.java`,这个文件通常会包含一个名为`...
其中,循环链表是一种常用的数据结构,它通过链式存储方式形成一个没有头尾之分的闭合结构,非常适合用来模拟这种环形排列的问题。 循环链表由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在Java中,...
在Java中解决约瑟夫问题,通常会使用单循环链表作为基础数据结构。我们可以创建一个Node类,包含数据(即人的编号)和对下一个节点的引用。然后,我们可以实现一个JosephusProblem类,它将维护这个链表,并提供解决...
类似约瑟夫环问题。有一群人组成一个圈。从头开始按照顺时针方向从1开始依次报数。报到到9的人就离开圈子。其左手边的人接着从1开始报数。依此进行,直到剩最后一个人为止。
本文将深入探讨“简单的双向循环链表”,并结合提供的`LinkedList.java`源码来理解其实现原理。 双向循环链表与单向链表不同,它在每个节点中不仅保存了指向下一个节点的指针,还保存了指向前一个节点的指针,这种...