概述
- 链表是一种线性数据结构 ,它通过指针 将一系列节点 连接起来,每个节点包含数据 和指向下一个节点的引用。
- 资料:
https://pan.quark.cn/s/43d906ddfa1b
一、链表的核心特点
- 非连续存储:节点在内存中可以分散存储,无需占用连续空间。
- 顺序访问 :只能通过前一个节点访问下一个节点,无法直接索引,时间复杂度为 O(n)。
- 动态大小:无需预先指定长度,可根据需要动态添加或删除节点。
- 元素异构:节点数据可以是不同类型(部分语言支持,如 Python)。
二、链表的基本操作
1. 访问元素
需从表头开始遍历,直到找到目标节点,时间复杂度 O(n)。
python
class Node:
def __init__(self, data):
self.data = data
self.next = None
# 遍历链表
def traverse(head):
current = head
while current:
print(current.data)
current = current.next
2. 插入元素
- 头部插入 :创建新节点,指向原表头,时间复杂度 O(1)。
- 中间插入 :找到插入位置的前一个节点,修改指针指向,时间复杂度 O(n)。
- 尾部插入 :遍历到表尾,将最后一个节点的指针指向新节点,时间复杂度 O(n)。
3. 删除元素
- 头部删除 :直接将表头指向第二个节点,时间复杂度 O(1)。
- 中间删除 :找到删除位置的前一个节点,修改指针跳过目标节点,时间复杂度 O(n)。
- 尾部删除 :遍历到倒数第二个节点,将其指针置为 None,时间复杂度 O(n)。
4. 查找元素
遍历链表,比较节点数据,时间复杂度 O(n)。
三、链表的优缺点
优点
- 动态扩容:无需预先分配内存,可灵活添加节点。
- 插入删除高效:仅需修改指针,不涉及元素移动(除遍历外)。
- 空间利用率高:仅存储必要的节点数据和指针,无冗余空间。
缺点
- 访问效率低:无法直接索引,需遍历查找。
- 内存开销大:每个节点需额外存储指针。
- 操作复杂:插入删除时需维护指针关系,容易出错。
四、链表的常见类型
- 单链表:每个节点仅指向下一个节点,只能单向遍历。
- 双链表:每个节点同时指向前一个和后一个节点,支持双向遍历。
- 循环链表:最后一个节点指向表头,形成闭环,可循环遍历。
五、链表的应用场景
- 频繁插入删除的场景(如链表式队列、栈)。
- 元素数量不确定的场景(如动态数据存储)。
- 内存碎片较多的场景(如嵌入式系统)。
六、数组与链表的对比
| 特性 | 数组 | 链表 |
|---|---|---|
| 存储方式 | 连续内存 | 非连续内存 |
| 访问效率 | O(1)(随机访问) | O(n)(顺序访问) |
| 插入删除效率 | O(n)(需移动元素) | O(1)(仅修改指针) |
| 空间利用率 | 高(无冗余指针) | 低(需存储指针) |
| 动态扩容 | 不支持(静态数组) | 支持(动态添加节点) |
| 适用场景 | 频繁访问、元素固定 | 频繁插入删除、元素动态 |
七、总结
链表是一种灵活的线性数据结构,核心优势是动态扩容 和高效的插入删除操作,适合处理元素数量不确定且需频繁修改的场景。若需频繁访问元素,建议使用数组。