二叉树
定义:A binary tree is a [[树|tree]] in which no node can have more than two children
遍历:
-
本质:二维结构序列化
问题:遍历过程中未访问儿子的存储(访问某个儿子后失去对原父亲的索引)
利用队列存储:BFS
利用堆栈存储:DFS(函数调用栈)
-
先序遍历:根左右
- 后序遍历:左右根
- 层次遍历:BFS
- 中序遍历:左根右
递归 \(\to\) 循环:
- 尾递归可直接转为循环
- 非尾递归利用栈可转循环
性质:前中后序遍历的堆栈操作完全相同(visit操作不影响堆栈操作)
推论:堆栈结构唯一确定树结构
循环实现中序遍历:
void iter_inorder(tree_ptr tree) {
Stack S = CreateStack(MAX_SIZE);
for (;;) {
for (;tree;tree = tree->Left) Push(tree, S); // 左边走到底
tree = Top(S); Pop(S); // 作为根被访问
if (!tree) break;
visit(tree->Element);
tree = tree->Right; // 向右走一步
}
}
void iter_preorder(tree_ptr tree) {
Stack S = CreateStack(MAX_SIZE);
for (;;) {
for (;tree;tree = tree->Left) {
Push(tree, S);
visit(tree->Element); // 作为左节点被访问
}
tree = Top(S); Pop(S);
if (!tree) break;
tree = tree->Right; // 向右走一步
}
}
表达式树的中缀遍历结果不一定是表达式的原始表达(需加括号)
线索二叉树:
- 背景:N节点二叉树具有2N指针域,但仅有N-1条边,空间利用率低
- 思想:让空指针域指向中序遍历的上/下一个节点
- 实现:增加一个比特,用来标记是否为线索/儿子
应用:树的遍历(增加一个特殊的head)
- 向左走到低
- 若为Thread,跳Thread
- 否则向右走一步,然后向左走到底,重复两步直至终止
n个元素构成不同二叉树的个数:
- In a binary tree, left child and right child are different.
-
计数:\(C_n=\sum C_i\cdot C_{n-i-1}\)
-
推广:n个元素构成的合法出栈序列
二叉树确定,则遍历时的进出栈序列唯一确定;进出栈序列唯一确定,则二叉树确定,二者具有对应关系
分类:
-
斜二叉树(Skewed Binary Trees)
-
完全二叉树(Skewed Binary Trees):All the leaf nodes are on two adjacent levels
性质:
- 第i层节点数最多\(2^{i-1},i\geqslant1\)
- \(k\)层深二叉树节点最多\(2^k-1,k\geqslant1\)
- 结论:\(n_0=n_2+1\)
- 推导:数边数:\(n_0+n_1+n_2-1=2*n_2+n_1\)