由一棵二叉树的中序与后序排列求出它的先序排列

题目链接:https://ac.nowcoder.com/acm/problem/14360

Description

给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度<=8)。

Input

两行,每行一个字符串,分别表示中序和后序排列

Output

一个字符串,表示所求先序排列

Sample Input
BADC
BDCA
Sample Output
ABCD
Solution

众所周知,二叉树的三种遍历方式
先序遍历:根–>左–>右
中序遍历:左–>根–>右
后序遍历:左–>右–>根
其实就是访问根结点的顺序决定的。

显然后序排列的最后一个字符是根结点位置的字符,这时候我们去遍历中序排列,找到其中与后序排列的最后一个字符相同的字符,那么在中序排列中这个位置的字符就是根结点位置的字符,在中序排列中这个位置前面的字符构成左子树,后面的字符构成右子树。
那我们由此递归求解就好,不断的重复上面所说的操作。找到根节点就将它输出,递归时,将左子树,右子树重新看成一个独立的树,去找到根节点,找到就将它输出。直到递归结束。说白了就是套娃

Code
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string a, b;
void before( int hl, int hr,int zl, int zr)
{
    if (zl == zr) {
        return;
    }
    int flag=-1;
    for (int i = 0; i < zr; i++) {
        if (a[i] == b[hr - 1]) {
            flag = i;
            cout << a[flag];
            break;
        }
    }
     before( hl, hl  + flag- zl,zl, flag);        //左子树
     before(hl+ flag - zl, hr - 1,flag + 1, zr);  //右子树
}
int main()
{
    cin >> a >> b;
    before( 0, b.length(),0, a.length());
}
  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: 由于中序后序排列已知,可以通过递归的方式求出先序排列。 先找到后序排列的最后一个元素,即为根节点。然后在中序排列中找到根节点的位置,将中序排列分成左子树和右子树两部分。接着递归处理左子树和右子树,直到叶子节点。 具体步骤如下: 1. 找到后序排列的最后一个元素,即为根节点。 2. 在中序排列中找到根节点的位置,将中序排列分成左子树和右子树两部分。 3. 根据左子树和右子树的元素个数,将后序排列分成左子树和右子树两部分。 4. 递归处理左子树和右子树,直到叶子节点。 5. 将根节点加入先序排列中。 最终得到的先序排列即为该二叉树先序排列。 例如,给出中序排列为[4, 2, 5, 1, 6, 3, 7],后序排列为[4, 5, 2, 6, 7, 3, 1],则可以得到先序排列为[1, 2, 4, 5, 3, 6, 7]。 ### 回答2: 求一棵二叉树先序遍历需要知道它的根节点位置,而中序遍历后序遍历无法直接确定根节点的位置。因此,我们需要先通过中序遍历后序遍历构建出这棵二叉树,然后再进行先序遍历。 具体步骤如下: 1. 后序遍历的最后一个节点肯定是二叉树的根节点,假设它是节点p。 2. 在中序遍历中找到节点p的位置,它将中序遍历序列分成了左子树和右子树两部分。 3. 根据左右子树的长度,在后序遍历中将序列分成两部分,分别对应左子树和右子树的后序遍历。 4. 对左子树和右子树分别递归执行上述步骤,构建出左子树和右子树。 5. 将根节点p加入先序遍历序列中,然后依次加入左子树和右子树的先序遍历序列,即为最终的先序遍历序列。 举个例子,假设中序遍历为[4, 2, 5, 1, 6, 3, 7],后序遍历为[4, 5, 2, 6, 7, 3, 1]。根据上述步骤,可以构建出如下的二叉树: ``` 1 / \ 2 3 / \ / \ 4 5 6 7 ``` 由于后序遍历的最后一个节点是1,因此1是根节点。在中序遍历中,4和5在1的左侧,2在其左侧,6和7在其右侧,3在其右侧,因此左子树的中序遍历为[4, 2, 5],右子树的中序遍历为[6, 3, 7]。同理,左子树的后序遍历为[4, 5, 2],右子树的后序遍历为[6, 7, 3]。按照上述步骤分别构建出左子树和右子树即可。最终的先序遍历序列为[1, 2, 4, 5, 3, 6, 7]。 总结起来,通过中序遍历后序遍历构建出二叉树的步骤如下: 1. 后序遍历的最后一个节点是二叉树的根节点。 2. 在中序遍历中找到根节点的位置,将中序遍历序列分成左子树和右子树两部分。 3. 根据左右子树的长度,将后序遍历序列分成左子树和右子树的后序遍历序列。 4. 分别对左子树和右子树递归执行上述步骤,构建出左子树和右子树。 5. 根节点加入先序遍历序列,然后依次加入左子树和右子树的先序遍历序列,得到最终的先序遍历序列。 ### 回答3: 我们可以使用递归的方式求解这个问题。先看一下先序中序后序排列的定义: - 先序遍历:先访问根节点,再遍历左子树和右子树。 - 中序遍历:先遍历左子树,再访问根节点,最后遍历右子树。 - 后序遍历:先遍历左子树,再遍历右子树,最后访问根节点。 根据后序排列,我们可以得到该二叉树的根节点,然后在中序排列中找到根节点所在的位置,这将中序排列分成了左子树和右子树两部分。再根据左子树和右子树的节点数量,将后序排列也分成了左子树和右子树两部分。这时我们就可以递归地对左子树和右子树进行求解,直到节点数量为1或0,即到达了叶子节点或者空节点。 对于每个子树,我们都可以通过递归得到它的先序排列。具体的方法是先输出根节点,再递归输出左子树和右子树的先序排列。 下面是一个Python实现: ```python def construct_tree(inorder, postorder): if len(postorder) == 0: return None root = TreeNode(postorder[-1]) index = inorder.index(postorder[-1]) left_inorder = inorder[:index] right_inorder = inorder[index+1:] left_size = len(left_inorder) right_size = len(right_inorder) left_postorder = postorder[:left_size] right_postorder = postorder[left_size:-1] root.left = construct_tree(left_inorder, left_postorder) root.right = construct_tree(right_inorder, right_postorder) return root def preorder_traversal(root): if root is None: return [] result = [root.val] result += preorder_traversal(root.left) result += preorder_traversal(root.right) return result inorder = [4,2,5,1,6,3,7] postorder = [4,5,2,6,7,3,1] root = construct_tree(inorder, postorder) print(preorder_traversal(root)) ``` 输出结果为:[1, 2, 4, 5, 3, 6, 7],即该二叉树先序排列

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值