线性表、栈与队列
引入
词汇
| English | 释义 | 拼音 |
|---|---|---|
| array/əˈreɪ/ | 数组 | shù zǔ |
| linked list/lɪŋkt lɪst/ | 链表 | liàn biǎo |
| node/nəʊd/ | 节点 | jié diǎn |
| stack/stæk/ | 栈 | zhàn |
| queue/kjuː/ | 队列 | duì liè |
两种布局,不同的端
- Python 列表是连续的数组 array:索引 $i$ 一步算出地址,但头部插入要全员挪动。链表 linked list 用便宜拼接换掉跳转:每个节点 node 带一个指向下一个的指针。
- 栈 stack 在同一端进出(后进先出);队列 queue 一端进另一端出(先进先出)。

{exercise:uni-cs0502-layouts}
练习
连续数组里取下标 i 的代价是——
难度 1/5 · 今日首次完成可获 100 金币及少量额外奖励
格子相邻排布:地址是算出来的,不是找出来的。
追加为何是摊还 O(1)
- 数组按倍增扩容:追加 $n$ 个元素时,每次元素在所有扩容中至多被复制一次,平均追加是常数。
- 头部插入永不摊还:每次
insert(0)都全员滑动——$n$ 次头插搬动 $\Theta(n^2)$ 个元素,$n$ 翻倍时计数翻两番。
{exercise:uni-cs0502-append}
练习
在 Python 列表末尾追加是——
难度 1/5 · 今日首次完成可获 100 金币及少量额外奖励
倍增扩容让每个元素总体至多复制一次,平均追加为常数。
轨迹
- 栈:
push 3, push 7, push 1后pop, pop返回 $1$ 再 $7$——后进先出。括号配对同法:扫([]){}压入开括号,闭括号必须匹配栈顶;([)]失败,因为)看到的是[。 - 队列:入队
a, b, c;两次出队返回a再b;队首是c。collections.deque两端都 $O(1)$——循环里list.pop(0)是经典 $O(n)$ 陷阱。
例子
两个栈可以拼出一个队列:收件箱加发件箱,每个元素至多被搬两次——所以真正的 deque 干脆原生支持两端。
{exercise:uni-cs0502-trace}
练习
push 3、push 7、push 1、pop、pop 依次返回——
难度 1/5 · 今日首次完成可获 100 金币及少量额外奖励
栈按逆压入序弹出:后进先出。