数据结构-链表

链表与顺序表的本质区别

在数据结构中,顺序表和链表是两种基本的线性表实现方式,它们的核心区别在于存储方式:

  • 顺序表:元素存储在连续的内存单元中,通过索引直接访问
  • 链表:元素可以存储在任意的内存单元中(连续或不连续),通过指针将分散的节点串联成逻辑上连续的序列

链表的基本构成

链表的最小单元是节点,每个节点包含两部分:

  • 数据域:存储节点本身的数据
  • 指针域:存储上一个或下一个节点的内存地址,使节点之间能够相互关联

单链表

单链表是最简单的链表结构,每个节点只有一个指针域,指向其后继节点。尾节点的next指针一定是NULL,且无法逆向访问(不能回头)。

单链表的基本操作

1. 头插法

头插法是将新节点插入到链表的头部:

  • 新节点的next指针指向当前头节点
  • 更新头指针指向新节点
  • 特点:插入顺序与最终链表顺序相反
2. 尾插法

尾插法是将新节点插入到链表的尾部:

  1. 找到当前尾节点(next指针为NULL的节点)
  2. 将尾节点的next指针指向新节点
  3. 新节点的next指针设为NULL
  4. 特点:插入顺序与最终链表顺序相同
3. 在指定位置插入数据
  1. 遍历链表,找到要插入位置的前一个节点
  2. 新节点的next指针指向插入位置的原节点
  3. 前一个节点的next指针指向新节点
4. 删除节点
  1. 找到要删除节点的前一个节点p
  2. 用指针q记录要删除的节点(p->next)
  3. 将p的next指针指向q的next节点(跳过q)
  4. 释放q节点的内存空间
5. 获取链表长度

从头节点开始遍历整个链表,每访问一个节点就计数加1,直到遇到尾节点(next为NULL)。

6. 释放链表

释放链表需要逐个释放所有节点:

  1. 让指针p指向头节点后的第一个节点
  2. 循环:
    • 用指针q记录p的后继节点
    • 释放p指向的节点
    • 让p指向q
    • 直到p为NULL
7. 双指针技巧

双指针技术在链表操作中非常实用,可用于:

  • 寻找链表的中间节点
  • 寻找倒数第k个节点
  • 判断链表是否有环等场景

基本思路是使用两个指针,根据需求以不同速度或不同起点移动。

单向循环链表

单向循环链表与单链表的区别在于:最后一个节点的指针不是指向NULL,而是指向头节点,形成一个闭环。

单向循环链表的特点

  • 遍历结束条件与单链表不同:
    • 单链表:p != NULLp->next != NULL
    • 单向循环链表:p != Lp->next != L(L为头节点)

环相关问题

1. 如何判断链表有环?

使用快慢指针法:

  • 设置两个指针,慢指针每次走1步,快指针每次走2步
  • 同时从链表头节点出发
  • 如果链表中存在环,快指针会在环内"追上"慢指针(两者指向同一节点)
  • 如果快指针先到达NULL,则链表无环
2. 如何找到环的入口?
  1. 先通过快慢指针确定链表有环
  2. 记录快慢指针相遇的节点
  3. 将慢指针重置到链表头节点
  4. 快慢指针以相同速度(每次1步)前进
  5. 两指针再次相遇的节点就是环的入口

双向链表

双向链表的每个节点有两个指针域:

  • 一个指向直接后继节点
  • 一个指向直接前驱节点

这种结构允许双向遍历,提高了某些操作的效率,但也增加了一定的存储空间开销。

双向链表的基本操作

1. 头插法
  1. 新节点的next指针指向当前头节点的next
  2. 新节点的prev指针指向头节点
  3. 若头节点的next不为NULL,更新其prev指针指向新节点
  4. 头节点的next指针指向新节点
2. 尾插法
  1. 找到当前尾节点(通常可维护一个尾指针直接获取)
  2. 新节点的prev指针指向尾节点
  3. 新节点的next指针设为NULL
  4. 尾节点的next指针指向新节点
  5. 更新尾指针指向新节点
3. 指定位置插入数据

需要同时维护前驱和后继指针的指向关系,确保双向引用正确。

4. 删除节点
  1. 找到要删除的节点p
  2. p的前驱节点的next指针指向p的后继节点
  3. 若p的后继节点不为NULL,其prev指针指向p的前驱节点
  4. 释放p节点的内存空间

顺序表与链表的对比

特性顺序表链表
存储空间连续不连续
访问效率高(随机访问,O(1))低(顺序访问,O(n))
插入删除效率低(需移动元素,O(n))高(只需修改指针,O(1))
空间分配静态分配,可能有内存浪费或溢出动态分配,按需分配
存储密度高(只需存储数据)低(需额外存储指针)
适用场景频繁访问,元素数量固定频繁插入删除,元素数量动态变化

简言之,顺序表是"以空间换时间",链表是"以时间换空间"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值