5 个常见的链表操作:
(1)单链表反转
(2)链表中环的检测
(3)两个有序的链表合并
(4)删除链表倒数第n个结点
(5)求链表的中间结点
public class LinkedListTest {
// 单链表反转
public static Node reverse(Node list) {
Node curr = list, pre = null; // 初始化当前节点为传入的链表头,前一个节点为null
while (curr != null) { // 当当前节点不为空时
Node next = curr.next; // 保存当前节点的下一个节点
curr.next = pre; // 将当前节点的下一个节点指向前一个节点(反转)
pre = curr; // 将当前节点设置为下一次迭代的前一个节点
curr = next; // 移动到下一个节点
}
return pre; // 返回反转后的头节点
}
// 检测环
public static boolean checkCircle(Node list) {
if (list == null) return false; // 如果链表为空,则没有环
Node fast = list.next; // 快指针
Node slow = list; // 慢指针
// 快慢指针法检测环
while (fast != null && fast.next != null) {
fast = fast.next.next; // 快指针每次走两步
slow = slow.next; // 慢指针每次走一步
if (slow == fast) return true; // 如果相遇,说明有环
}
return false; // 否则没有环
}
// 删除倒数第K个结点
public static Node deleteLastKth(Node list, int k) {
Node fast = list; // 快指针
int i = 1;
while (fast != null && i < k) { // 移动快指针到第k个节点
fast = fast.next;
++i;
}
if (fast == null) return list; // 如果k大于链表长度,返回原链表
Node slow = list; // 慢指针
Node prev = null; // 慢指针的前一个节点
while (fast.next != null) { // 当快指针没有到达链表末尾
fast = fast.next; // 快指针移动
prev = slow; // 保存慢指针的前一个节点
slow = slow.next; // 慢指针移动
}
if (prev == null) { // 如果删除的是头节点
list = list.next;
} else { // 删除慢指针指向的节点
prev.next = prev.next.next;
}
return list; // 返回新链表头节点
}
// 求中间结点
public static Node findMiddleNode(Node list) {
if (list == null) return null; // 如果链表为空,返回null
Node fast = list; // 快指针
Node slow = list; // 慢指针
// 快慢指针法找中间节点
while (fast != null && fast.next != null) {
fast = fast.next.next; // 快指针每次走两步
slow = slow.next; // 慢指针每次走一步
}
return slow; // 返回中间节点
}
// 打印链表
public static void printAll(Node list) {
Node p = list; // 从链表头开始
while (p != null) { // 遍历链表
System.out.print(p.data + " "); // 打印当前节点数据
p = p.next; // 移动到下一个节点
}
System.out.println(); // 输出换行
}
// 创建新节点
public static Node createNode(int value) {
return new Node(value, null); // 创建新节点,next为null
}
// 节点类定义
public static class Node {
private int data; // 节点存储的数据
private Node next; // 指向下一个节点的指针
// 节点构造函数
public Node(int data, Node next) {
this.data = data; // 初始化数据
this.next = next; // 初始化下一个节点
}
// 获取节点数据
public int getData() {
return data;
}
}
}
学习:极客时间《数据结构与算法之美》学习笔记