PAT 1020 Tree Traversals[二叉树遍历]
1020 Tree Traversals (25)(25 分)
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
题目大意:在二叉树中,其关键字是互不相通的正整数,给出其后根遍历(postorder)和中根遍历(inorder ),要求给出其层次遍历的顺序。
//其实没太做过二叉树的题目。果断放弃,查答案。代码来自:https://www.liuchuo.net/archives/2100
//不一定根节点就是n。
//因为后根遍历中最后一个节点一定是根节点。
#include <iostream> #include <vector> #include<stdio.h> using namespace std; vector<int> post, in, level(100000, -1);//level是一个size为100000,初始化为-1 //因为N<=30,层数为30的,最多有2^30-1个节点。这好像也放不开啊。。 //root指向当前遍历段的根节点,开始下标(指向中根遍历),结束下标(指向中根遍历),层次遍历的下标。 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++;//while循环在中根遍历中找到根。 //后根遍历中最后一个点一定是整棵树的根,从而分为左子树与右子树。 level[index] = post[root];//当前层次遍历就是根节点。 pre(root - 1 - end + i, start, i - 1, 2 * index + 1); //遍历左子树,index中存放的是层次遍历的结果。 pre(root - 1, i + 1, end, 2 * index + 2); //遍历右子树,根据二叉树的存储特性,左子树是2*当前+1,右子树是2*当前+2; } int main() { int n, cnt = 0; scanf("%d", &n); post.resize(n); in.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); for(int i = 0; i < level.size(); i++) { if (level[i] != -1) {//index可能是-1,表示那个节点为空。 if (cnt != 0) printf(" "); printf("%d", level[i]); cnt++; } if (cnt == n) break; } return 0; }
//另有中后遍历转前序遍历代码:
#include <cstdio> using namespace std; int post[] = {3, 4, 2, 6, 5, 1}; int in[] = {3, 2, 4, 1, 6, 5}; void pre(int root, int start, int end) { if(start > end) return ; int i = start; while(i < end && in[i] != post[root]) i++;//在中序遍历中找到根节点 printf("%d ", post[root]);//打印根节点 pre(root - 1 - end + i, start, i - 1);//遍历 pre(root - 1, i + 1, end); } int main() { pre(5, 0, 5); return 0; }
//感觉不要更牛一点。🐮