0
点赞
收藏
分享

微信扫一扫

PAT_甲级_1020 Tree Traversals (25分) (C++)【树的遍历】


目录

​​1,题目描述​​

​​ 题目大意​​

​​2,思路​​

​​树的遍历​​

​​数据结构 ​​

​​关键点​​

​​3,代码​​

1,题目描述

PAT_甲级_1020 Tree Traversals (25分) (C++)【树的遍历】_PAT

Sample Input:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

 

Sample Output:

4 1 6 3 5 7 2

 题目大意

根据给出的二叉树的postorder(后序遍历) and inorder(中序遍历),输出level(层次遍历)

 

 

 

 

2,思路

参考柳神的思路。

学过数据结构的同学可能比较清楚,通过树的中序和后序遍历,可以构建一颗完整的二叉树,根据得出的二叉树并利用队列,可以得到层次遍历。

在这里,可以利用中序和后续遍历推出先序遍历,只需要在先序遍历过程中记录节点的下标,按下标排序后,输出的值即为层次遍历的输出结果。

 

树的遍历

由中序和后序遍历如何推出二叉树,可以参考这篇文章​​@那记忆微凉 【已知中序遍历和后序遍历,画出此二叉树】​​

  • 先序遍历:根左右
  • 中序遍历:左根右
  • 后序遍历:左右根

数据结构 

  • struct node{int index, value;}:index按层次遍历时输出的先后顺序,value输出的值;
  • vector<int> in, post:存放树的两种遍历顺序;
  • vector<node> ans:存放最终答案

关键点

以题目中所给例子为参考: 

postOrder:2 3 1 5 7 6 4

inOrder:1 2 3 4 5 6 7

PAT_甲级_1020 Tree Traversals (25分) (C++)【树的遍历】_甲级_02

  • 后序遍历的最后一个节点(4)为二叉树的根节点。这个根节点将整棵树(中序遍历中)分成了左右两棵子树,左子树节点为1 2 3、右子树节点为5 6 7;
  • 在后序遍历(2 3 1 5 7 6 4)中可以看出,左子树的根节点为1,右子树的根节点为6;(将一棵大树,划分为两棵小树,这就是递归的原理)
  • 具体实现时,以后序遍历为准,在中序遍历找到根节点位置得出左右子树的节点数目,确定后序遍历新的始末位置,进行递归;
  • 显然在遍历过程中,先确定根节点,然后确定左右子树的根节点……这便是层次遍历的输出顺序,因此,在遍历时,只需加上index值,使其在向下遍历时不断递增(左子树:2*index+1, 右子树:2*index+2),然后按照index排序,输出value值即可;
  • pre(root-(end-i)-1, start, i - 1, 2 * index + 1)(递归求左子树)这里说明一下,左子树的根节点如何确定:root(原根节点在后序遍历中的位置),i(根节点在中序遍历中的位置),end-i(右子树节点数目),-1(即左子树根节点在后序遍历中的位置);

3,代码

#include<iostream>
#include<stdio.h>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

struct node{
int index, value;
};
bool cmp(node a, node b){
return a.index < b.index;
}
vector<node> ans;
vector<int> in, post;

//root start end均指后序遍历时的下标
void pre(int root, int start, int end, int index){ //递归实现
if(start > end) return;//
int i = start;
while(i <= end && in[i] != post[root]) i++; //找到根节点(后序遍历的最后一个节点)在中序遍历序列中的位置
ans.push_back({index, post[root]}); //根节点入栈
pre(root-(end-i)-1, start, i - 1, 2 * index + 1); //递归处理左右两棵子树 并更新index(index可能不连续)
pre(root - 1, i + 1, end, 2 * index + 2);

}

int main(){
//#ifdef ONLINE_JUDGE
//#else
// freopen("1.txt", "r", stdin);
//#endif

int n;
scanf("%d", &n);
in.resize(n);
post.resize(n);
for(int i = 0; i < n; i++) scanf("%d", &post[i]);
for(int i = 0; i < n; i++) scanf("%d", &in[i]);

pre(n-1, 0, n-1, 0);
sort(ans.begin(), ans.end(), cmp);
printf("%d", ans[0].value);
for(int i = 1; i < ans.size(); i++){
printf(" %d", ans[i].value);
}

return 0;
}

 

举报

相关推荐

0 条评论