循环链表
特点:
在整个链表当中没有最后一个结点。
当链表中只有一个结点的时候,那么这个结点的下一个结点是他本身。
Java实现代码
package com.xingyun.linked;
/*
*
* 循环链表的实现。不存在最后一个结点。
* 具体变化,就是将之前单链表的最后一个结点的下一个结点指向这个链表的头结点
* */
public class LoopNode {
// 定义属性,结点的携带值
int data;
// 指向的下一个结点的地址
LoopNode next = this;
// 构造方法,构造出一个新的结点,需要携带一个数值的参数,表示当前结点的携带数据
public LoopNode(int data) {
this.data = data;
}
// 获取下一个结点
public LoopNode next() {
return this.next;
}
// 拿到当前结点的数据
public int getData() {
return this.data;
}
// 显示所有结点
public void getAll() {
// 获取当前结点(一般为链表的头结点)
LoopNode current = this;
while (true) {
// 打印当前结点的值
System.out.print(current.data + "\t");
// 当前结点已经打印完毕,此处需要向后继续递进,在当前类中的方法直接采用属性来递进,当然也可以调用方法
current = current.next;
// 如果递进一个结点,且这个节点的下一个指向的结点是当前链表的起始结点,那么该链表遍历完毕
if (current.next() == this) {
System.out.print(current.data + "\t");
break;
}
}
System.out.println();
}
// 删除一个结点
// 因为这是单链表的删除,所以删除是通过断开前一个结点与下一个结点的联系来实现删除
// 也就是直接拿当前结点的下下一个结点来作为当前结点的下一个结点,直接将当前结点的下一个结点剔除
public void remove() {
// 断开当前结点与下一个结点直接的联系
this.next = this.next.next;
}
// 插入一个结点
// 因为是单链表,所以只能插入到当前结点后面
// 具体原理:先找一个临时存储区(一个新的结点对象)来记录当前结点的下一个结点
// 其次,将要插入的结点直接赋值作为当前结点的下一个结点。
// 最后,当前结点的下一个结点是要插入的新结点,直接将临时存储区中的结点作为
// 当前结点的下下一个结点。
public void after(LoopNode n1) {
// 创建临时存储区来记录当前结点的下一个结点
LoopNode node = this.next;
// 将要插入的结点直接作为当前结点的下一个结点
this.next = n1;
// 当前结点的下下一个结点再去链接临时存储区中的结点
this.next.next = node;
}
public static void main(String[] args) {
// 创建链表的头结点
LoopNode node = new LoopNode(1);
// 创建其余结点
LoopNode node1 = new LoopNode(2);
LoopNode node2 = new LoopNode(3);
LoopNode node3 = new LoopNode(4);
LoopNode node4 = new LoopNode(5);
// 因为循环链表不存在最后一个结点,所以必须使用插入的方法来创建链表
node.after(node1);
node1.after(node2);
node2.after(node3);
node3.after(node4);
node4.after(new LoopNode(7));
// 打印当前链表中的所有结点信息
node.getAll();
// 删除node的下一个结点,也就是node1
node.remove();
// 再次查看当前链表中的数据,看是否删除成功
node.getAll();
}
}
双向循环链表
每一个结点有三个成员,一个是本身的数据成员,一个是指向下一个结点的成员,一个是指向上一个结点的成员。
如果只有一个结点的时候,他的上一个结点是他自己,下一个结点也是他自己。
Java实现代码
package com.xingyun.linked;
public class DoubleNode {
DoubleNode pre = this;
int Data;
DoubleNode next = this;
public DoubleNode(int data) {
this.Data = data;
}
// 获取数据
public int getData() {
return this.Data;
}
// 获取下一个结点
public DoubleNode next() {
return this.next;
}
// 获取上一个结点
public DoubleNode pre() {
return this.pre;
}
// 创建双向循环链表,追加
public void after(DoubleNode node) {
// 创建临时变量存储器来存储当前结点的下一个结点
DoubleNode nextnext = this.next;
// 将追加的结点置于当前结点的下一个结点
this.next = node;
// 将追加的结点的上一个结点置于当前结点
node.pre = this;
// 将原来的下一个结点组为当前追加的结点的下一个结点
node.next = nextnext;
// 将原来的下一个结点的上一个结点置为当前追加的结点
nextnext.pre = node;
}
public static void main(String[] args) {
DoubleNode node1 = new DoubleNode(1);
DoubleNode node2 = new DoubleNode(2);
DoubleNode node3 = new DoubleNode(3);
DoubleNode node4 = new DoubleNode(4);
// 输出第一个结点的当前结点的值、上一个结点的值、下一个结点的值,
System.out.print(node1.getData() + "\t");
System.out.print(node1.pre.getData() + "\t");
System.out.println(node1.next.getData() + "\t");
// 追加,创建链表
node1.after(node2);
node2.after(node3);
node3.after(node4);
System.out.println("----------------------------");
// 输出第一个结点的当前结点的值、上一个结点的值、下一个结点的值,
System.out.print(node1.getData() + "\t");
System.out.print(node1.pre.getData() + "\t");
System.out.print(node1.next.getData() + "\t");
System.out.println(node1.next().next().getData() + "\t");
}
}