C++算法练习-day38——106.从中序和后序遍历序列构造二叉树

题目来源:. - 力扣(LeetCode)

题目思路分析

题目要求根据一棵二叉树的中序遍历(inorder)和后序遍历(postorder)结果重建这棵二叉树。中序遍历的特点是左子树 -> 根节点 -> 右子树,而后序遍历的特点是左子树 -> 右子树 -> 根节点。利用这两个遍历的特点,我们可以递归地重建整棵树。

  1. 后序遍历的最后一个元素是根节点:因为后序遍历是左子树 -> 右子树 -> 根节点的顺序,所以最后一个元素一定是当前子树的根节点。
  2. 在中序遍历中找到根节点的位置:一旦确定了根节点,我们可以在中序遍历中找到这个根节点的位置,这个位置将中序遍历分为左子树和右子树两部分。
  3. 递归构建左右子树:根据中序遍历中根节点的位置,我们可以将后序遍历也分为两部分,分别对应左子树和右子树。然后递归地对这两部分进行中序和后序遍历的重建。

代码:

/**  
 * Definition for a binary tree node.  
 * struct TreeNode {  
 *     int val;  
 *     TreeNode *left;  
 *     TreeNode *right;  
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}  
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}  
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}  
 * };  
 */  
class Solution {  
public:  
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {  
        int n = postorder.size();  
        if (n == 0) {  
            // 如果后序遍历为空,说明子树为空  
            return nullptr;  
        }  
        // 后序遍历的最后一个元素是根节点  
        TreeNode* node = new TreeNode(postorder[n-1]);  
        if (postorder.size() == 1) {  
            // 如果后序遍历只有一个元素,说明整棵树只有一个节点  
            return node;  
        }  
        int incise;  
        // 在中序遍历中找到根节点的位置  
        for (incise = 0; incise < inorder.size(); incise++) {  
            if (inorder[incise] == postorder[n-1]) {  
                break;  
            }  
        }  
        // 根据根节点的位置,将中序遍历和后序遍历分割为左右子树  
        vector<int> leftinorder(inorder.begin(), inorder.begin() + incise);  
        vector<int> rightinorder(inorder.begin() + incise + 1, inorder.end());  
        vector<int> leftpostorder(postorder.begin(), postorder.begin() + leftinorder.size());  
        vector<int> rightpostorder(postorder.begin() + leftinorder.size(), postorder.end() - 1);  
        // 递归构建左右子树  
        node->left = buildTree(leftinorder, leftpostorder);  
        node->right = buildTree(rightinorder, rightpostorder);  
        return node;  
    }  
};

知识点摘要

  1. 二叉树遍历
    • 中序遍历:左子树 -> 根节点 -> 右子树
    • 后序遍历:左子树 -> 右子树 -> 根节点
  2. 递归
    • 递归是一种在函数内部调用自身的方法,常用于解决可以分解为相似子问题的问题。
  3. 动态数组(vector)
    • 在C++中,vector是一个可以动态调整大小的数组,提供了方便的元素访问和操作方法。

通过本题,我们学习了如何利用二叉树的中序遍历和后序遍历结果来重建二叉树。这种方法依赖于递归,通过在后序遍历中找到根节点,然后在中序遍历中分割出左右子树,再递归地对左右子树进行同样的操作。这种方法不仅锻炼了我们对二叉树遍历的理解,还加深了对递归思想的应用。在实际编程中,递归是一种强大的工具,可以帮助我们解决许多看似复杂的问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neophyte0608

你的鼓励将使我创作学的更加快乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值