(中序后序)还原二叉树

数据结构实验之二叉树八:(中序后序)求二叉树的深度

Problem Description
已知一颗二叉树的中序遍历序列和后序遍历序列,求二叉树的深度。

Input
输入数据有多组,输入T,代表有T组数据。每组数据包括两个长度小于50的字符串,第一个字符串表示二叉树的中序遍历,第二个表示二叉树的后序遍历。

Output
输出二叉树的深度。

Sample Input

2
dbgeafc
dgebfca
lnixu
linux

Sample Output

4
3

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <memory.h>

using namespace std;

typedef struct node tree;
struct node
{
    char data;
    struct node* left;
    struct node* right;
};
tree* create_tree(int n,char a[],char b[])
{
    tree* p;
    p=(tree*)malloc(sizeof(tree));
    p->data=a[n-1];
    if(n==0)
        return NULL;
    else
    {
        int i;
        for(i=0; i<n; i++)
        {
            if(a[n-1]==b[i])
            {
                break;
            }
        }
        p->left=create_tree(i,a,b);
        p->right=create_tree(n-1-i,a+i,b+1+i);
    }
    return p;
}
int depth_tree(tree* root)
{
    if(!root)
    {
        return 0;
    }
    else
    {
        return max(1+depth_tree(root->left),1+depth_tree(root->right));
    }
}
int main()
{
    char a[55],b[55];
    int n;
    cin>>n;
    while(n--)
    {
        cin>>a>>b;
        tree* root=(tree*)malloc(sizeof(tree));
        root = create_tree(strlen(a),b,a);
        cout<<depth_tree(root)<<endl;
    }
    return 0;
}

### 算法实现:根据中后序遍历还原二叉树 在树的深度优先遍历中,中后序遍历的结果可以用于还原原始的二叉树结构。中遍历提供了根节点在子树中的位置信息,而后序遍历的最后一个元素总是当前子树的根节点[^1]。通过递归的方式,可以从后序遍历中提取根节点,并利用中遍历将左右子树划分出来。 具体步骤如下: - 从后序遍历中获取当前子树的根节点。 - 在中遍历中找到该根节点的位置,将其划分为左子树和右子树。 - 根据左子树和右子树的大小,将后序遍历也划分为对应的左右区间。 - 对左右子树递归执行上述步骤,直到构建完整个二叉树。 以下是基于上述逻辑的 C++ 实现代码: ```cpp struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1); } private: TreeNode* build(vector<int>& inorder, vector<int>& postorder, int inStart, int inEnd, int postStart, int postEnd) { if (inStart > inEnd) return nullptr; // 创建当前子树的根节点 TreeNode* root = new TreeNode(postorder[postEnd]); // 在中遍历中找到根节点的位置 int rootIndex = inStart; for (int i = inStart; i <= inEnd; ++i) { if (inorder[i] == root->val) { rootIndex = i; break; } } // 计算左子树的节点数量 int leftSubtreeSize = rootIndex - inStart; // 递归构建左子树和右子树 root->left = build(inorder, postorder, inStart, rootIndex - 1, postStart, postStart + leftSubtreeSize - 1); root->right = build(inorder, postorder, rootIndex + 1, inEnd, postStart + leftSubtreeSize, postEnd - 1); return root; } }; ``` ### 时间与空间复杂度分析 该算法的时间复杂度为 $O(n)$,其中 $n$ 是节点总数。每个节点都会被处理一次,且每次查找根节点在中遍历中的位置需要线性时间[^2]。空间复杂度为 $O(h)$,其中 $h$ 是树的高度,这主要是由于递归调用栈所占用的空间。 如果希望进一步优化性能,可以通过引入哈希表来存储中遍历中每个值对应的位置索引,从而将查找根节点的时间复杂度降低到 $O(1)$,整体时间效率会有所提升[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值