算法-二叉树 - (本质 递归)
数据结构
struct {
int value;
Node* left;
Node* right;
} Node;
经典题目
1. 中序遍历
解法:递归
visit(root->left, result);
result.push(root);
visit(root->right, result);
解决2:迭代
while(root != null && stack != null) {
// visit left tree to stack
while(root != null..) {
stack.push(root);
root = root->left;
}
// visit central Node
root = stack.pop()
result.push(root)
// visit right Tree
root = root.right
}
2. 对称二叉树
首先定义和抽象问题。
满足如下条件,两棵树是对称的。
1). 根节点具有相同的值
2). 每棵树的右子树和另一棵树的左子树对称。
解法1:递归
解法2:迭代
利用队列,分别判断两棵树判断左节点和右节点。
3. 二叉树的最大深度
比较简单,递归即可,空时返回。
4. 反转二叉树。
递归。先翻转,再递归;先递归,最后再翻转。两种都可以。
5. 二叉树的直径
递归。定义和抽象问题:直径 = 左子树的深度 + 右子树的深度 + 1
6. 合并二叉树
递归。深度优先。
7. 验证二叉搜索树
递归。需要注意,二叉搜索树中,整个左子树都要<x.key,因此在递归时,需要传入上界和下界。遍历root的左子树时,更新upper bound为root.key;遍历右子树时,更新lower bound 为root.key。初始root的lower/upper bound 为-inf, inf。
8. 二叉树的层序遍历
a. 递归
递归时传入level,作为层数的数组索引。vector< vector<int> > ans;
b. 队列
先进先出,设计层数。每处理一个节点,往队列中Push其子节点。可以证明队列的处理顺序跟层序保持一致。
9. 从前序与中序遍历序列构造二叉树
树的本质还是递归。
前序遍历: 根 左子树 右子树
中序遍历:左子树 根 右子树
如何递归构造?在前序数组中先找到根节点,然后根据根节点,在中序数组中计算得到左子树的长度以及右子树的长度;
拿到左右子树的长度后,就可以递归构造下一个根节点的左右子树了(知道了它们的根节点在前序数组中的位置)。
(中序遍历不直接参与构造树,它参与确定节点和树的位置)