首页/数据结构/线性表/双链表和循环链表 🔗 在 Obsidian 中打开
数据结构 · 线性表

双链表和循环链表

难度 ★★★重要度 ★★★★ 考查频率 高题型 选择 / 代码填空 / 画图 双链表循环链表
速查
双链表结点含 prior/data/next,可双向遍历、已知节点删除/前插 $O(1)$。循环链表首尾相连、无 NULL 指针;循环双链表插入删除最简洁(无需判边界)。循环单链表判空:$L->next==L$。

概述

在单链表基础上扩展出双链表(加前驱指针)和循环链表(首尾相连),以换取更灵活的操作或减少边界判断。

核心概念

一、双链表

每个结点含 priordatanext,可双向遍历。在 p 之后插入 s 的四步:

s->next = p->next;      // ①
p->next->prior = s;   // ②(需 p->next != NULL)
s->prior = p;          // ③
p->next = s;           // ④
约束② 必须在 ④ 之前完成对原后继的访问,否则会丢失原后继指针。若 p 是尾结点,② 不需执行。

二、循环单链表

尾结点 next 指向头结点而非 NULL。判空:$L->next == L$。

三、循环双链表

头结点 prior 指向尾结点、尾结点 next 指向头结点;不存在 NULL 指针,插入删除无需判边界。

对比

特性单链表双链表循环单链表循环双链表
指针数1212
判空next==NULL同左next==Lnext==L
插入 O(1)仅后插前后均可仅后插前后均可
反向遍历

手算示例

双链表后插:L ⇄ [1] ⇄ [2] ⇄ [3],在 [1] 后插 [4]:

$s->next=[2]$,$[2]->prior=s$,$s->prior=[1]$,$[1]->next=s$ → L ⇄ [1] ⇄ [4] ⇄ [2] ⇄ [3]。

循环单链表尾插:输入 1,2,3,尾指针 r 始终指向末结点,$r->next=L$。

常见考法

命题套路双链表插入语句顺序、循环链表判空条件、删除需改几个指针、约瑟夫环用循环单链表。

易错点

必记
  1. 双链表插入②须在①之后(否则丢失原后继)。
  2. p 为尾结点时不需要 $p->next->prior=s$。
  3. 循环链表判空是 $next==L$ 而非 $next==NULL$。
  4. 循环双链表头结点 prior、next 都指向自己。

核心结论

  1. 双链表:空间换时间,可 $O(1)$ 找前驱/后继。
  2. 循环链表:无 NULL 指针,适合环形操作。
  3. 循环双链表:插入删除最简洁,无需判边界。
  4. 应用:约瑟夫环(循环单链表)、浏览器前进后退(双链表)。

记忆卡片

双链表后插四语句?
①s->next ②p->next->prior ③s->prior ④p->next
循环单链表判空?
$L->next == L$
循环双链表判空?
$L->next == L$(或 $L->prior==L$)
双链表多存什么?
前驱指针 prior,可 O(1) 找前驱
循环双链表为何简洁?
无 NULL,不需边界判断
约瑟夫环用哪种?
循环单链表

交互动画 · 循环双链表头插 / 尾插 / 删除

带头结点循环双链表 L:next 环(上,橙)+ prior 环(下,紫) next next next 回环 prior prior prior 回环 L 5 9 表长:0
L.next = L;L.prior = L(空表自环)
点击「播放」或「下一步」:从空表开始,演示头插 5、尾插 9、再删除 5

相关知识点

singly-linked-list-implementation linear-list-applications

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。