1020. Tree Traversals
来源:互联网 发布:yum 安装pip 编辑:程序博客网 时间:2024/05/16 01:48
题目
Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (<=30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.
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
基本思路
考察二叉树的建树,前序/中序/后续/层序遍历等基本操作。
1.通过后序序列和中序序列构造二叉树,然后层序遍历输出。层序遍历用BFS实现。需要注意的是,BFS中队列queue存放的是结点地址,即queue<node*> q
,而不是结点queue<node> q
。因为队列中存放的是原元素的一个副本,若队列中存放的是node型,那么当需要修改队首元素时,就无法修改原元素(修改的只是队列中的副本),因此让队列存放元素的地址(即node*型),这样可以通过访问地址去修改原元素。(虽然本题不涉及修改元素,只是简单的输出,但这个细节要重视,不然往后出现问题错哪里都搞不清楚)。
代码
#include<cstdio>#include<queue>using namespace std;const int maxn = 35;struct node{ int data;//数据域 node* lchild; node* rchild;//指针域 };int in[maxn],post[maxn];//中序序列,后序序列int n;//结点个数 //由中序遍历序列和后续遍历序列建树//后续序列post[postL,postR],中序序列in[inL,inR] node* creat(int postL,int postR,int inL,int inR){ if(postL > postR) return NULL; node* root = new node;//定义根结点 root->data = post[postR]; int k; for(k=inL;k<=inR;k++){//确定中序序列中根结点的位置 if(in[k] == post[postR]){ break; } } int numLeft = k - inL;//左子树的结点数 root->lchild = creat(postL,postL+numLeft-1,inL,k-1);//遍历左子树 root->rchild = creat(postL+numLeft,postR-1,k+1,inR); return root;//返回根结点 } //层序遍历输出,用BFS实现int num = 0;//输出的个数 ,用于控制格式 void BFS(node* root){ queue<node*> q;//定义队列,存放的是结点的位置 q.push(root);//根结点入队 while(!q.empty()){ node* top = q.front();//取出队首元素 q.pop(); printf("%d",top->data); num++; if(num < n) printf(" ");//控制格式 if(top->lchild != NULL) q.push(top->lchild); if(top->rchild != NULL) q.push(top->rchild); }} int main(){ scanf("%d",&n); for(int i=0;i<n;i++){//输入后序遍历序列 scanf("%d",&post[i]); } for(int i=0;i<n;i++){//输入中序遍历序列 scanf("%d",&in[i]); } node* root = creat(0,n-1,0,n-1); BFS(root); return 0;}
拓展
本题是通过后序序列和中序序列构造二叉树,基本思路是:后序序列的最后一个元素为根结点,然后在中序序列中找到该根结点,中序序列左侧即为左子树,右侧即为右子树,然后分别进行递归;若是要通过前序序列和中序序列 构造二叉树,原理完全是一样的,只是根结点在前序序列的第一个元素。那么,若要通过中序序列和层序序列 构造二叉树呢,思路就有些不同了。分析如下:
1.层序序列的第一个元素是当前树的根结点,然后在中序序列中找到该根结点,根结点左侧即为左子树,右侧为右子树。
2.但是在层序序列中,左(右)子树的结点时分散开的,无法像前序/后序序列那样直接递归。因此,不妨开两个vector<int> layerLeft,layerRight
,每当在中序序列中确定一个根结点时,就遍历当前层序序列的所有结点,把左子树的结点push进layerLeft,右子树的结点push进layerRight,然后可利用layerLeft,layerRight进行递归。
代码
//通过层序遍历和中序遍历构造二叉树,当前层序遍历结点存放在layer,中序遍历序列为[inL,inR] node* creat(vector<int> layer,int inL,int inR){ if(layer.size() == 0) return NULL; node* root = new node;//新建结点 root->data = layer[0];//根结点的值为层序序列的第一个元素 root->lchild = root->rchild = NULL; int k; for(int i=inL;i<=inR;i++){//在中序序列中找到根结点 if(in[i] == layer[0]){ k = i; break; } } vector<int> layerLeft,layerRight;//左右子树层序遍历的结点 for(int i=1;i<layer.size();i++){//遍历层序序列,找出分别属于左、右子树的结点 bool isLeft = false; for(int j=inL;j<k;j++){//对于每个层序序列的元素,遍历中序序列的左子树,从而判断该结点是否属于左子树 if(layer[i] == in[j]){ isLeft = true; break; } } if(isLeft){//如果是左子树的结点 layerLeft.push_back(layer[i]); }else{ layerRight.push_back(layer[i]); } } root->lchild = creat(layerLeft,inL,k-1);//递归左子树 root->rchild = creat(layerRight,k+1,inR); return root;//返回根结点地址}
- 1020. Tree Traversals
- 1020. Tree Traversals (25)
- 1020. Tree Traversals
- 【PAT】1020. Tree Traversals
- 1020. Tree Traversals (25)
- 1020. Tree Traversals (25)
- PAT 1020. Tree Traversals
- PAT 1020. Tree Traversals
- 1020. Tree Traversals
- 1020. Tree Traversals
- 1020. Tree Traversals (25)
- 1020. Tree Traversals (25)
- 1020. Tree Traversals (25)
- 1020.Tree Traversals
- 1020. Tree Traversals (25)
- 1020. Tree Traversals (25)
- 1020. Tree Traversals (25)
- 1020. Tree Traversals
- 音频自动化测试
- PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
- IntelliJ IDEA 工具技巧
- (二)Java程序设计之Hello World程序
- sshfs的使用
- 1020. Tree Traversals
- 数据结构的堆栈 与Java中的堆栈
- Android Studio的安装过程记录
- 【codeforces 777C】 Alyona and Spreadsheet
- 从Android设备中提取内核和逆向分析
- 自定义异常与编译时运行时异常
- MongoDB文档翻译-CRUD操作-删除文档
- 【Java】数组--利用冒泡算法给日期排序
- 使用Visual Studio 2010制作安装包