星图 · 活页

数据如何拥有秩序

数据结构的五个小实验:把数字压进栈、排进队列、串成链表,把一棵树按四种顺序走一遍,再看冒泡排序怎么把乱序推回正轨,最后做三道题验一验。

讲义 · 数据结构

数据很多。秩序从哪儿来?

数据结构不是一张要背的名词表,而是组织信息、安排操作次序的一套想法。下面五个实验都能动手—— 凡是能点、能按的地方都试一遍,比死记“先进先出”四个字有用得多。

  • 约 12 分钟
  • 4 类结构
  • 5 个互动实验
01

栈与队列:顺序决定规则

两种结构都能装下一串数据,区别只在取出的顺序。往里面放几个数字试试。

一句话分清:栈像一摞盘子,最后放上去的最先拿走;队列像排队买票,先来的人先离开。

▤ 栈 Stack

LIFO · Last In, First Out —— 后进先出

栈顶 TOP ↑
还空着

栈是空的,先放一个数字进去。

入栈 O(1)出栈 O(1)看栈顶 O(1)

⇥ 队列 Queue

FIFO · First In, First Out —— 先进先出

队首 →122436→ 队尾

队首在左,队尾在右。

入队 O(1)*出队 O(1)**取决于实现方式

02

链表:让节点彼此相连

数组把元素摆在连续的内存里;链表由节点组成,每个节点存着数据,另存一个指向下一个节点的引用。

动手接一条链表

加节点、删头节点,看 HEAD 指向怎么跟着变。

HEAD → … → NULL
HEAD →369→ NULL

每个节点只需要知道下一个节点在哪里。

数组与链表,各有所长

没有绝对的赢家,只有合不合适。

数组 按下标取元素很快:O(1)

但在中间插入或删除,往往要把后面的一大串挪位置。


链表 已知位置时改连接很方便:O(1)

但要找第 k 个元素,通常只能从头一个个走过去:O(n)。

记住这个画面

链表不是“挨在一起”,而是“指向彼此”。

数据→ next数据→ next数据→ NULL

顺着 next 一路走,就能访问到整条链;代价是没法“跳着看”。

03

树:把层级关系摊开

文件夹、组织架构、语法分析,都能用树来描述。遍历就是约定一套次序,把每个节点都访问一遍。

二叉树遍历实验

换一种次序,看同一棵树被访问的先后如何变化。

根 → 左 → 右
ABCDEFG
前序遍历

先访问根节点,再遍历左子树,最后遍历右子树。可以用来复制一棵树。

播放后,这里按访问顺序排出节点。

顺带一提:二叉搜索树满足“左子树都更小、右子树都更大”,对它做中序遍历,得到的正好是有序序列。

04

排序实验室:看算法怎么干活

同一组数字,不同的比较与交换策略会走出不同的路径。这里用冒泡排序看相邻元素如何一步步归位。

冒泡排序 Bubble Sort

比较相邻两项,顺序不对就交换。一轮下来,最大的那个会被推到最右边。

比较次数:0

点「下一步」,看算法先比较哪两个数字。朱砂实心表示正在比较的两个,浅朱砂表示已经归位的那一段。

已归位正在比较第 0 轮

平均时间 O(n²)最坏时间 O(n²)适合教学,不适合大数组

05

检查一下,真的理解了吗

不用背定义,拿刚才动手的经验回答就好。三道题,选完立刻给解析。

答对 0 题选一个你认为对的。
  1. 问题 1 / 3栈中依次压入 A、B、C,第一次出栈会得到什么?

三道都答完,按钮会变成重新练习。

✓

把这些收进工具箱

挑结构时别先问“哪个最厉害”,先问“我最频繁的操作是什么”。

顺序本身就是规则

栈和队列存的是同一批数据,差别只在“谁先离开”。选之前先问自己:我要按什么顺序取?

挨在一起,还是指向彼此

数组按下标直达,链表靠指针串门。频繁按下标读用数组,频繁在两头增删用链表。

遍历是访问的次序

同一个结构,换一种遍历就换一种视角。排序则是用比较和交换,把无关紧要的次序试出来。

抽象看不懂的时候,就把它拆成能点的东西。

这里的图示都是教学用的简化模型:真实的语言实现、内存布局与复杂度分析,比这一页讲的要细得多。

← 回到轨道