用一组连续的存储单元,按层序编号存储二叉树的结点。
#define MaxSize 100
typedef struct {
ElemType data[MaxSize]; // 从下标 1 开始存储
int n; // 结点数
} SqBiTree;
A
/ \
B C
/ \ \
D E F
存储为:[_, A, B, C, D, E, _, F](下标 0 不用;6 号位空缺,因为 C 没有左孩子)
| 树形 | 顺序存储表现 |
|---|---|
| 完全二叉树 | ✅ 最适合,空间无浪费 |
| 满二叉树 | ✅ 最适合 |
| 普通二叉树 | ⚠️ 可能浪费大量空间(用 0 / 空填充) |
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild; // 左右孩子指针
} BiTNode, *BiTree;
┌──────────┬──────────┬──────────┐
│ lchild │ data │ rchild │
│ 左孩子 │ 数据域 │ 右孩子 │
└──────────┴──────────┴──────────┘
证明:
仍用上面的树($n=6$):
A: lchild→B, rchild→C
B: lchild→D, rchild→E
C: lchild=NULL, rchild→F
D: lchild=NULL, rchild=NULL
E: lchild=NULL, rchild=NULL
F: lchild=NULL, rchild=NULL
空指针数 $= D(2)+E(2)+F(2)+C(1) = 7 = 6+1$ ✓
typedef struct TriTNode {
ElemType data;
struct TriTNode *lchild, *rchild, *parent; // 增加父指针
} TriTNode, *TriTree;
┌──────────┬──────────┬──────────┬──────────┐
│ parent │ lchild │ data │ rchild │
│ 双亲指针 │ 左孩子 │ 数据域 │ 右孩子 │
└──────────┴──────────┴──────────┴──────────┘
| 存储方式 | 适用场景 | 查找孩子 | 查找双亲 | 空间 |
|---|---|---|---|---|
| 顺序存储 | 完全 / 满二叉树 | $O(1)$ | $O(1)$ | 可能浪费 |
| 二叉链表 | 通用 | $O(1)$ | $O(n)$ | $n+1$ 个空指针 |
| 三叉链表 | 需频繁找双亲 | $O(1)$ | $O(1)$ | $3n$ 个指针 |
完全二叉树有 100 个结点,用顺序存储需要多少空间?
二叉树有 50 个结点,二叉链表中有多少空指针?
空指针数 $= n+1 = \textbf{51}$。
顺序存储:[_, A, B, C, D, E, _, F, G]
| 下标 $i$ | 结点 | 双亲 $\lfloor i/2\rfloor$ | 是左还是右 |
|---|---|---|---|
| 1 | A | — | 根 |
| 2 | B | 1 = A | 左($2=2\times1$) |
| 3 | C | 1 = A | 右($3=2\times1+1$) |
| 4 | D | 2 = B | 左 |
| 5 | E | 2 = B | 右 |
| 6 | 空 | 3 = C | C 无左孩子 |
| 7 | F | 3 = C | 右 |
| 8 | G | 4 = D | 左($8=2\times4$) |
A
/ \
B C
/ \ \
D E F
/
G
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。