Java 循环链表的实现
循环链表是一种特殊的链表结构,它的尾节点指向头节点,形成一个环。这使得从链表的任何一个节点出发都能遍历到链表中的所有节点。在实际应用中,循环链表常用于构建环形队列、游戏中的玩家回合等场景。
1. 循环链表的结构设计
在 Java 中实现循环链表,我们需要定义一个节点类(Node)和一个循环链表类(CircularLinkedList)。节点类包含数据和指向下一个节点的引用,而循环链表类则包含对头节点的引用及与链表相关的各种操作方法。
1.1 节点类
节点类的设计如下:
public class Node {
int data; // 节点数据
Node next; // 指向下一个节点的引用
public Node(int data) {
this.data = data;
this.next = null; // 初始化时,设置下一个节点为 null
}
}
1.2 循环链表类
循环链表类的主要功能包括插入节点、删除节点、遍历链表等。
public class CircularLinkedList {
private Node head; // 指向链表头部的引用
// 构造函数
public CircularLinkedList() {
this.head = null;
}
// 插入节点到链表末尾
public void insert(int data) {
Node newNode = new Node(data);
if (head == null) {
head = newNode;
newNode.next = head; // 指向自身,形成循环
} else {
Node temp = head;
while (temp.next != head) { // 遍历到最后一个节点
temp = temp.next;
}
temp.next = newNode; // 将最后节点的 next 指向新节点
newNode.next = head; // 新节点的 next 指向头节点
}
}
// 遍历链表
public void traverse() {
if (head == null) return;
Node temp = head;
do {
System.out.print(temp.data + " ");
temp = temp.next;
} while (temp != head);
System.out.println();
}
// 删除指定节点
public void delete(int key) {
if (head == null) return;
Node current = head;
Node previous = null;
// 如果删除的是头节点
if (current.data == key) {
// 处理链表只有一个节点的情况
if (current.next == head) {
head = null; // 链表为空
return;
} else {
// 找到最后一个节点以更新指针
while (current.next != head) {
current = current.next;
}
current.next = head.next; // 更新最后节点的 next
head = head.next; // 更新头节点
}
return;
}
// 遍历链表找到要删除的节点
do {
previous = current;
current = current.next;
} while (current != head && current.data != key);
if (current.data == key) {
previous.next = current.next; // 跳过要删除的节点
}
}
}
1.3 类图
以下是循环链表的类图表示:
classDiagram
class Node {
+int data
+Node next
+Node(int data)
}
class CircularLinkedList {
-Node head
+CircularLinkedList()
+void insert(int data)
+void traverse()
+void delete(int key)
}
Node --> CircularLinkedList : contains
2. 功能测试
接下来,我们可以创建一个简单的测试程序来验证我们的循环链表实现。
public class Main {
public static void main(String[] args) {
CircularLinkedList cll = new CircularLinkedList();
cll.insert(1);
cll.insert(2);
cll.insert(3);
System.out.print("链表内容: ");
cll.traverse(); // 输出: 1 2 3
cll.delete(2);
System.out.print("删除 2 后的链表内容: ");
cll.traverse(); // 输出: 1 3
cll.delete(1);
System.out.print("删除 1 后的链表内容: ");
cll.traverse(); // 输出: 3
}
}
3. 开发过程甘特图
在开发循环链表的过程中,我们可以使用甘特图来描述各个阶段的时间安排如下:
gantt
title 循环链表开发过程
dateFormat YYYY-MM-DD
section 设计
理解问题 :done, des1, 2023-10-01, 1d
设计类结构 :done, des2, after des1, 1d
section 实现
编写节点类 :done, imp1, after des2, 1d
编写循环链表类 :done, imp2, after imp1, 2d
section 测试
编写测试代码 :done, test1, after imp2, 1d
运行测试 :done, test2, after test1, 1d
4. 总结
通过以上实现,我们成功地构建了一个基本的循环链表,并实现了一系列常用的方法。循环链表的特点是节点之间形成环状结构,能够有效地支持插入、删除和遍历操作。这种数据结构在实际编程中非常有用,特别是在需要处理重复循环的场景中。希望通过这个示例,你能够深入理解循环链表的工作原理及其应用。