题目描述
给定一个树的先序和中序的遍历结果,构建一棵树,并输出这个棵树的层序遍历和后序遍历结果。注:这棵树的结点是由整数描述
输入
树结点总数m
先序输出序列
中序输出序列
输出
层序输出序列
后续输出序列
样例输入
10
1 2 5 10 3 6 13 7 14 15
2 10 5 1 6 13 3 14 7 15
样例输出
1 2 3 5 6 7 10 13 14 15
10 5 2 13 6 14 15 7 3 1
二叉树的重建时很多大公司笔试的题目,非常的常见。
对于我们来说(可能是因为我太菜了),理解起来比较困难。
其实,整体还是运用递归的思想
下面这张图,我感觉能让大家理解其具体的流程
这里给大家推荐一个B站视频,我就是看了这个视频,才理解了整个过程
视频
这位up主用的是java实现,不过影响不大,咱们主要就是去理解整个过程,对递归有一个更进一步的理解
看完之后,有没有一种恍然大悟的感觉(如果没有,可能是因为我说的还不够通俗易懂)。
思路理解之后,另外的难题就是代码了
#include <iostream>
#include <queue>
using namespace std;
struct Node {
int data;
Node* lchild;
Node* rchild;
Node(Node* lc=nullptr, Node* rc = nullptr) {
lchild = lc;
rchild = rc;
}
Node(const int& elem, Node* lc = nullptr, Node* rc = nullptr) {
data = elem;
lchild = lc;
rchild = rc;
}
};
Node* BuildTree(int* pre, int* med,int len) {
//len为中序的长度
if (len == 0) return NULL;//当中序长度为0时结束
int k = 0;
while (med[k] != pre[0]) k++;//在中序列中寻找根
Node* root = new Node(pre[0]);//创建根节点
//利用指针的移动,去对子树进行递归
root->lchild = BuildTree(pre + 1, med, k);
root->rchild = BuildTree(pre + k + 1, med + k + 1, len - k - 1);
return root;
}
void PosOrder(Node* root) {//后序输出
if (root != nullptr) {
PosOrder(root->lchild);
PosOrder(root->rchild);
cout << root->data << " ";
}
}
void sequence(Node* root) {//层序输出,利用BFS的思想
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node* tree = q.front();
q.pop();
cout << tree->data << " ";
if(tree->lchild != nullptr)
q.push(tree->lchild);
if(tree->rchild != nullptr)
q.push(tree->rchild);
}
}
int main() {
int n;
cin >> n;
int* pre = new int[n];
int* med = new int[n];
for (int i = 0; i < n; i++)
cin >> pre[i];
for (int i = 0; i < n; i++)
cin >> med[i];
Node* tree = BuildTree(pre,med,n);
sequence(tree);
cout << endl;
PosOrder(tree);
cout << endl;
return 0;
}
核心代码只有这么几句
Node* BuildTree(int* pre, int* med,int len) {
//len为中序的长度
if (len == 0) return NULL;//当中序长度为0时结束
int k = 0;
while (med[k] != pre[0]) k++;//在中序列中寻找根
Node* root = new Node(pre[0]);//创建根节点
//利用指针的移动,去对子树进行递归
root->lchild = BuildTree(pre + 1, med, k);
root->rchild = BuildTree(pre + k + 1, med + k + 1, len - k - 1);
return root;
}
这里运用了指针的移动来实现子树的提取,其实就是得到子树对应的前序与中序,实现递归
欢迎交流