从中序遍历和后序遍历序列创建二叉树

从中序遍历和后序遍历序列创建二叉树

思路分析

二叉树相关的很多问题的解决思路都有分治法的思想在里面。

分治法的思想:把原问题分解(Divide)成若干个与原问题结构相同但规模更小的子问题,待子问题解决(Conquer)以后,再合并(Combine)它们,原问题就得以解决,“归并排序” 和 “快速排序” 都是分治法思想的应用,其中 “归并排序” 先无脑地“分”,在 “合” 的时候就麻烦一些;“快速排序” 开始在 partition 上花了很多时间,即在 “分” 上使了很多劲,然后就递归处理下去就好了,没有在 “合” 上再花时间。

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]

在这里插入图片描述
具体思路参考:
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/qian-xu-bian-li-python-dai-ma-java-dai-ma-by-liwei/

C语言实现

 struct TreeNode {
     int val;
     struct TreeNode *left;
     struct TreeNode *right;
 };
 
struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize){
    if (inorderSize == 0) {
        return NULL;
    }
    struct TreeNode* root = malloc(sizeof(struct TreeNode));
    root->val = postorder[postorderSize - 1];
    int i;
    for (i = 0; i < inorderSize; i++) {
        if (inorder[i] == postorder[postorderSize - 1]) {
            break;
        }
    }
    root->left = buildTree(inorder, i, postorder, i);
    root->right = buildTree(inorder + i + 1, inorderSize - i - 1, postorder + i, postorderSize - i - 1);
    return root;
}
<think>嗯,用户问的是如何理解二叉树的中序遍历序列后序遍历序列。我需要先回忆一下这两种遍历方式的具体定义步骤。中序遍历是左-根-右的顺序,而后序遍历则是左-右-根。接下来,可能需要解释如何通过这些序列来重建二叉树,或者它们各自的特点应用场景。 首先,要明确两种遍历的结果有什么不同。例如,后序遍历的最后一个元素肯定是根节点,而中序遍历中根节点将序列分成左右子树。这样可以利用后序找到根,再在中序中找到左右子树的节点,递归构建二叉树。可能需要举个例子来说明这个过程。 然后,我应该解释为什么这两个序列可以唯一确定一棵二叉树,前提是树中的节点值唯一。如果有重复的值,可能无法唯一确定。还要提到,单独一个遍历序列是不够的,需要至少两个不同遍历方式的组合才能重建树的结构。 另外,可能需要给出一个具体的代码示例,比如如何用C++实现根据中序后序序列重建二叉树。这部分要注意递归函数的写法,参数传递的是序列的索引范围,以及如何分割左右子树。 在解释过程中,要确保步骤清晰,比如:1. 从后序序列末尾取根节点;2. 在中序中找到根的位置,分割左右子树;3. 递归处理左右子树。同时,要注意边界条件,比如当序列为空时的处理。 最后,可能还要提到这两种遍历的应用场景,比如中序遍历在二叉搜索树中可以得到有序序列后序遍历常用于先处理子节点再处理父节点的场景,比如释放内存。 在回答之后,按照用户的要求,提出相关问题。这些问题应该围绕遍历方法、重建二叉树的其他组合、应用场景等展开。例如,前序中序的组合如何重建,不同遍历方式的时间复杂度,或者为什么某些组合无法重建二叉树。</think><< 中序遍历后序遍历二叉树遍历的两种重要方式,它们的序列特征组合可以唯一确定二叉树结构(假设节点值唯一)。以下是具体理解方式: 1. **中序遍历序列(Left-Root-Right)**: 特征:根节点位于序列中间,左侧是左子树所有节点,右侧是右子树所有节点 示例:对于二叉树: A / \ B C 中序序列为 [B, A, C] 2. **后序遍历序列(Left-Right-Root)**: 特征:最后一个元素一定是当前树的根节点 示例:上述二叉树后序序列为 [B, C, A] 3. **组合重建原理**: - 后序序列末尾元素确定根节点 - 在中序序列中找到该根节点位置,分割左右子树 - 根据子树节点数量,划分后序序列中的左右子树范围 - 递归处理左右子树 示例代码实现重建: ```cpp #include <vector> #include <unordered_map> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; class Solution { unordered_map<int, int> inorder_map; int post_idx; TreeNode* build(vector<int>& inorder, vector<int>& postorder, int in_left, int in_right) { if (in_left > in_right) return nullptr; int root_val = postorder[post_idx--]; TreeNode* root = new TreeNode(root_val); int index = inorder_map[root_val]; root->right = build(inorder, postorder, index + 1, in_right); root->left = build(inorder, postorder, in_left, index - 1); return root; } public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { post_idx = postorder.size() - 1; for (int i = 0; i < inorder.size(); ++i) inorder_map[inorder[i]] = i; return build(inorder, postorder, 0, inorder.size() - 1); } }; ``` 关键点解释: 1. 后序序列从后往前处理(根->右->左的顺序) 2. 需要哈希表快速定位中序序列中的根节点位置 3. 递归时需要准确计算子树在序列中的边界索引 4. 必须先构建右子树再构建左子树(因为后序倒序处理)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值