链表概述
链表是一种线性数据结构,但与数组不同,它不需要连续的内存空间。每个元素(称为节点)包含实际数据和一个指向列表中下一个节点的指针。这种结构使得链表在插入和删除操作上比数组更加高效。
单向链表详解
单向链表是最简单的链表形式,每个节点只包含一个指向前一节点或后一节点的链接。链表的起始点称为头节点,结束点称为尾节点,尾节点的指针通常指向空值null,表示链表的结束。
在单向链表中,插入和删除操作非常高效,因为这些操作仅需更改相关节点的指针,而无需移动其他数据。
插入操作示例:
删除操作示例:
然而,由于链表中的数据不是连续存储的,因此它不支持随机访问。查找特定数据时,必须从头节点开始逐个检查每个节点,直到找到目标数据。
特殊类型的链表
循环链表
循环链表是一种特殊的单向链表,其尾节点的指针指向头节点,形成一个闭环。这种结构在某些应用场景下非常有用,如实现循环队列。
双向链表
双向链表在每个节点中增加了对前驱节点的引用,这使得双向链表可以在前后两个方向上自由导航。虽然这会增加一些存储开销,但在需要频繁进行双向遍历的情况下,双向链表提供了更高的效率。
链表的常见操作
单链表反转
public static Node reverse(Node list) { Node curr = list, pre = 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; }
两个有序链表的合并
public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode soldier = new ListNode(0); ListNode p = soldier; while (l1 != null && l2 != null) { if (l1.val
删除链表倒数第n个结点
public static Node deleteLastKth(Node list, int k) { Node fast = list; int i = 1; while (fast != null && i
求链表的中间结点
public static Node findMiddleNode(Node list) { if (list == null) return 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); } 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; } }
链表与数组的比较
链表和数组是两种基本的数据结构,它们各有优缺点,适用于不同的场景。了解它们之间的区别有助于选择合适的数据结构以满足具体需求。
数组的特点
优点 | 缺点 |
---|
支持随机访问 | 插入和删除操作效率低 |
查找速度快 | 可能造成内存浪费 |
数组大小固定 | 难以动态扩展 |
链表的特点
优点 | 缺点 |
---|
插入和删除操作快 | 不支持随机访问 |
内存利用效率高 | 查找效率低,需要遍历 |
大小可动态调整 | |