1. 双亲表示法:用数组存储,每个结点记录双亲位置。找双亲 $O(1)$,找孩子需遍历 $O(n)$。
typedef struct { ElemType data; int parent; } PTNode; // parent = 双亲下标
typedef struct { PTNode nodes[MaxSize]; int n; } PTree;
2. 孩子表示法:每个结点用链表存储所有孩子。找孩子方便,找双亲需遍历。
typedef struct CTNode { int child; struct CTNode *next; } CTNode;
typedef struct { ElemType data; CTNode *firstchild; } CTBox; // 孩子链表头
typedef struct { CTBox nodes[MaxSize]; int n, r; } CTree; // r = 根位置
3. 孩子兄弟表示法(二叉链表):找第一个孩子 $O(1)$、找下一个兄弟 $O(1)$,可转换为二叉树。
typedef struct CSNode {
ElemType data;
struct CSNode *firstchild, *nextsibling; // 第一个孩子、右兄弟
} CSNode, *CSTree;
A
/ | \ 孩子兄弟表示:
B C D A → firstchild → B → nextsibling → C → nextsibling → D
/ \ ↓
E F E → nextsibling → F
树 → 二叉树(左孩子右兄弟):
二叉树 → 树(逆过程):加线(左孩子的右链逐级连回父)、去线(删除所有右孩子连线)、层次调整。
森林 → 二叉树:先将每棵树转为二叉树,再把各树根视为兄弟用右指针连接。
森林遍历:先序遍历(访问第一棵根→子树→剩余森林)等价二叉树先序;中序遍历等价二叉树中序。
A
/ | \
B C D
/ \
E F
A
/
B
/ \
E C
\ \
F D
树1: A 树2: G
/ \ |
B C H
各树先转二叉树,再把根 A 和 G 用右指针连接。
A → G | | B H \ C
| 遍历方式 | 结果 |
|---|---|
| 树先根 | A B C D |
| 树后根 | B C D A |
| 对应二叉树先序 | A B C D |
| 对应二叉树中序 | B C D A |
| 存储方式 | 找双亲 | 找孩子 | 空间 |
|---|---|---|---|
| 双亲表示 | O(1) | O(n) | n 个结点 |
| 孩子表示 | O(n) | O(1) | n + 边数 |
| 孩子兄弟 | O(n) | O(1) | 2n 指针 |
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。