二叉树

116 阅读3分钟

二叉树的存储方式

  • 链式存储
  • 顺序存储

image.png

image.png

二叉树的遍历方式

dfs

  • 前序遍历 (递归 迭代)
  • 中序遍历 (递归 迭代)
  • 后续遍历 (递归 迭代)

递归写法

前序
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
中序
void traversal(TreeNode* cur, vector<int>& vec) {
    if (cur == NULL) return;
    traversal(cur->left, vec);  // 左
    vec.push_back(cur->val);    // 中
    traversal(cur->right, vec); // 右
}
后序
void traversal(TreeNode* cur, vector<int>& vec) {
    if (cur == NULL) return;
    traversal(cur->left, vec);  // 左
    traversal(cur->right, vec); // 右
    vec.push_back(cur->val);    // 中
}

迭代写法(用栈进行模拟)

前序遍历
vector<int> preorderTraversal(TreeNode *root) {
    stack<TreeNode *> st;
    vector<int> result;
    if (root == nullptr) return result;
    st.push(root);
    while (st.size()) {
        auto temp = st.top();
        st.pop();
        result.push_back(temp->val);
        if (temp->right) st.push(temp->right);
        if (temp->left) st.push(temp->left);
    }
    return result;
}
中序遍历
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
    vector<int> ans;
    stack<TreeNode*> st;
    auto cur = root;
        while (cur || st.size()){
            if (cur) st.push(cur),cur = cur->left;
            else{
                cur = st.top();
                st.pop();
                ans.push_back(cur->val);
                cur = cur->right;
            }
        }
        return ans;
    }
};

后序遍历

vector<int> postorderTraversal(TreeNode *root) {
    stack<TreeNode *> st;
    vector<int> result;
    if (root == nullptr) return result;
    st.push(root);
    while (st.size()) {
        auto temp = st.top();
        st.pop();
        result.push_back(temp->val);
        if (temp->left) st.push(temp->left);
        if (temp->right) st.push(temp->right);

    }
    reverse(result.begin(), result.end());
    return result;
}

bfs

  • 层序遍历 (迭代) 代码很好实现就不过多去关注代码了

226. 翻转二叉树

  • 递归做法 比较好理解注意递归函数的定义和函数结束递归条件
  • 迭代写法 前序遍历的递归写法

101. 对称二叉树

  • 注意遍历的顺序
  • 用bfs每次取两个头节点也是很好的选择

100. 相同的树

和101简直如出一辙 做法极其相似 都有递归和迭代两种做法

104. 二叉树的最大深度

dfs和bfs都能轻松求解

111. 二叉树的最小深度

同样用dfs和bfs都能轻松解决 遇到左右孩子都为空的节点直接返回

222. 完全二叉树的节点个数

  • 不利用完全二叉树性质的常规做法 用dfs和bfs统计节点个数
  • 利用完全二叉树性质的做法 利用递归统计左右子树的深度 如果是满二叉树直接返回 如果不是满二叉树再进行递归求解

110. 平衡二叉树

本质是用dfs或者bfs来求树的最大深度 迭代法不好写就不写了 (逃!

257. 二叉树的所有路径

通过dfs来找到所有的路径 来找出答案

404. 左叶子之和

  • 迭代法就用前中后序遍历都是可以的
  • 递归法就是直接做清晰递归函数的含义以及什么结束递归函数

513. 找树左下角的值

  • dfs做法 先递归左子树 再来做右子树 记录一个depth 当depth被更新时就更新一下value
  • bfs做法 利用队列先进先出的规律当堆中只剩一个元素且左右节点均为空就是答案

112. 路径总和

  • dfs搜索就完事了

113. 路径总和 II

  • dfs搜索

106. 从中序与后序遍历序列构造二叉树

根据后续遍历中的最后一个节点确定根节点是什么 然后去中序遍历中进行切割 找到左右子树 然后根据长度去后续遍历中进行第二次切割 递归下去