求中序遍历

#include <iostream>
#include <cstring>
#include <unordered_map>

using namespace std;

const int N = 35;
int n;
int postorder[N], inorder[N];
unordered_map<int, int>pos, l, r;
int q[N];

int build(int il, int ir, int pl, int pr)
{
    int root = postorder[pr];
    int k = pos[root];//将k定位到中序遍历的根节点

    if (il < k)//如果左子树存在
        l[root] = build(il, k - 1, pl, pl + k - 1 - il);
    if (ir > k)//如果右子树存在
        r[root] = build(k + 1, ir, pl + k  - il, pr - 1);
    return root;
}

void bfs(int root)
{
    int hh = 1, tt = 1;
    q[1] = root;
    while (hh <= tt)//while队列不空
    {
        int t = q[hh++];//取出队头元素
        if (l.count(t))//若左孩子存在,左孩子入队
            q[++tt] = l[t];
        if (r.count(t))//若右孩子存在,右孩子入队
            q[++tt] = r[t];
    }
    cout << q[1];
    for (int i = 2; i <= n; i++)
        cout << ' ' << q[i];
    cout << endl;
}


int main()
{
    
    cin >> n;
    getchar();
    for (int i = 1; i <= n; i++)
        cin >> postorder[i];
    for (int i = 1; i <= n; i++)
    {
        cin >> inorder[i];
        pos[inorder[i]] = i;//快速按值查找中序遍历元素位置
    }

    int root = build(1,n,1,n);
    bfs(root);
    return 0;
}
先序遍历和后序遍历是树的两种遍历方法。在某些情况下,如果已知一棵树的先序遍历序列和后序遍历序列,可以通过特定的算法得该树的中序遍历序列。这里的关键在于利用先序和后序遍历的特性,先序遍历的第一个元素总是树的根节点,而后序遍历的最后一个元素也是树的根节点,此外后序遍历的最后一个元素之前的部分是所有子树的后序遍历序列,先序遍历的第二个元素开始到某个元素之间的部分是同一子树的先序遍历序列。通过这个特性,可以递归地构造整棵树,进而得到中序遍历序列。 具体步骤如下: 1. 先序遍历的第一个元素是树的根节点。 2. 在后序遍历序列中找到根节点,那么根节点之前的部分就是左子树的后序遍历,根节点之后的部分就是右子树的后序遍历。 3. 在先序遍历中,找到左子树的先序遍历序列(从根节点的下一个元素开始,直到左子树的节点数结束)和右子树的先序遍历序列(从左子树的结束位置开始,直到右子树的节点数结束)。 4. 对左子树和右子树递归地应用以上步骤,直到子树只有一个节点或者为空。 5. 对于每个子树,按照左子树的中序遍历、根节点、右子树的中序遍历的顺序组合成子树的中序遍历序列。 6. 最后,将所有子树的中序遍历序列拼接起来,即得到整棵树的中序遍历序列。 注意,这种方法假设树中没有重复元素,并且我们需要知道树的结构或者节点之间的关系才能使用这种方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值