思路:
-
先根据后序和中序遍历结果构造二叉树
-
按层次遍历构造出来的二叉树
第一步:构造二叉树
-
存储结构使用两个哈希表:leftChile, rightChile。leftChile[i] = j: i 的左儿子是j,rightChilet同理
-
后序遍历的最后一个节点是跟节点,得到根节点后,递归构造根节点的左儿子和右儿子。
-
返回二叉树的根节点
-
也可以选择其他方式构造二叉树。
第二步:遍历二叉树
按层次遍历二叉树,使用bfs
-
根节点入队列。
-
当队列非空,队头的左右儿子入队列,队头出队。
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include<memory>
using namespace std;
const int N = 35;
int n;
int inorder[N], postorder[N];
unordered_map<int, int > leftChile, rightChile;//哈希表保存树,leftChile[i] = j: i 的左儿子是j,rightChilet同理
unordered_map<int, int > h;//保存中序遍历中各节点的位置
int dfs(int postorder[], int inorder[], int l1, int r1, int l2, int r2)//构造二叉树
{
if (l1 > r1) return 0;//没有节点,返回0
int root = postorder[r1];//根结点为后续遍历的最后一个节点
int k = h[root];//找到根节点在序遍历中的位置
leftChile[root] = dfs(postorder, inorder, l1, k - 1 - l2 + l1, l2, k - 1);//构造左儿子
rightChile[root] = dfs(postorder, inorder,r1-1 - (r2 - (k +1)) , r1 -1, k + 1, r2);//构造右儿子
return root;
}
int main()
{
cin >> n;//输入
for (int i = 0; i < n; i++)
cin >> postorder[i];
for (int i = 0; i < n; i++)
{
cin >> inorder[i];
h[inorder[i]] = i;//保存中序遍历中各个节点的位置
}
int root = dfs(postorder, inorder, 0, n - 1, 0, n - 1);//构造二叉树
//数组模拟队列
int q[N], hh = 0, tt = -1;//按层次遍历
if (root)//非0 表示有节点
q[++tt] = root;
while (hh <= tt)
{
int t = q[hh++];
if (leftChile[t]) q[++tt] = leftChile[t];//非0 为节点,入队列
if (rightChile[t]) q[++tt] = rightChile[t];//非0 为节点,入队列
}
for (int i = 0; i <= tt; i++)//队列中保存的就是按层次遍历的结果
cout << q[i] << " ";
return 0;
}
求个点赞~
树的知识不熟悉,通过前序跟后序可以吗
前序 后序不行, 得前序和中序或者 后序和中序. 因为前序 + 后序不能清楚的判断根节点.
中序加前或后才行
只有以下三种情况可确立一棵二叉树:
简单来说就是:
前、后、层
确定根节点;中序
确定左右子树菜鸟另外补充:
4. (先序+后序)&&真二叉树 —> 唯一二叉树
5. 先序+后序 —> 层序
图画得真好%%%
为什么要用哈希表存,什么情况下用哈希表
可以解释一下(l1, k - 1 - l2 + l1, l2, k - 1)与(r1-1 - (r2 - (k +1)) , r1 -1, k + 1, r2)怎么来的吗
先用后序遍历确定root嘛对吧,然后在中序遍历找到root的下标位置,列个等式就出来啦
大佬我想请教一下,在:
for (int i = 0; i < n; i++)
{
cin >> inorder[i];
h[inorder[i]] = i;//保存中序遍历中各个节点的位置
}
如果写成h[i] =inorder[i];则会爆栈,这是为什么呀
include memory 有啥用么
$/LaTex$
$\LaTeX$
$\LaTex$
inorder和postorder数组作为全局变量,在dfs函数中为什么还要用[]读取呢
不用也可以
“Chile”是不是打错了
好像是,
children