1. 程式人生 > >PTA (Advanced Level)1020 Tree Traversals

PTA (Advanced Level)1020 Tree Traversals

Tree Traversals

  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 (≤), 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

題目解析
  本題第一行給出二叉樹的結點數量n,之後第二行給出二叉樹的後序遍歷,第三行給出二叉樹的中序遍歷,要求輸出二叉樹的層序遍歷。(保證樹中的每個結點資料都不同)

  後序遍歷中最後一個元素便是當前樹的根結點,在中序遍歷中找到根結點對應的值,其左側便是左子樹的中序遍歷,在知道左子樹中序遍歷後可以根據結點數量在後續遍歷中找到左子樹的後續遍歷,確定了左子樹與根結點後剩下的便是右子樹資訊了,以此類推可以得到整棵二叉樹。

  建立二叉樹後使用廣搜,由於廣搜二叉樹維護佇列時,每次出隊一個結點並將其對應的左孩子與右孩子入隊,這就是層序遍歷。

  AC程式碼

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 35;
 4 int postorder[maxn];    //儲存後續遍歷
 5 int inorder[maxn];      //儲存中序遍歷
 6 struct node{    //二叉樹結點資訊
 7     int data;
 8     node *lchild;
 9     node *rchild;
10     node(int tdata){    //建構函式
11         data = tdata;
12         lchild = NULL;
13         rchild = NULL;
14     }
15 };
16 node *create(int postL, int postR, int inL, int inR){   
17     //由於要遞迴建樹我們並不需要將每個樹的左子樹右子樹的後序遍歷與中序遍歷儲存下來
18     //只需要在原始postorder與inorder陣列中標記出其位置即可
19     //postL與postR表示當前後續遍歷的左右兩端,inL與inR表示當前中序遍歷的左右兩端
20     if(postL > postR)   //如果後續遍歷左端位置大於右端位置,證明當前正在建立的樹為空樹
21         return NULL;
22     node *root = new node(postorder[postR]);    //建立根結點,權值為postorder[postR]左右子樹都為空
23     int i;
24     for(i = inL; inorder[i] != postorder[postR]; i++);  //在中序遍歷中找到根結點
25     int lenl = i - inL; //記錄左子樹長度
26     root->lchild = create(postL, postL + lenl - 1, inL, inL + lenl - 1);
27     //建立左子樹
28     root->rchild = create(postL + lenl, postR - 1, inL + lenl + 1, inR);
29     //建立右子樹
30     return root;
31 }
32 int n;  //n記錄結點數量
33 void levelorder(node *root){    //層序遍歷
34     if(root == NULL)    
35         return;
36     queue<node*> Q;
37     Q.push(root);   //根結點入隊
38     int cnt = 0;    //記錄當前已經輸出了幾個數,用於之後判斷是否輸出空格
39     while(!Q.empty()){
40         cnt++;
41         node *top = Q.front();
42         Q.pop();
43         printf("%d", top->data);//輸出結點權值
44         if(cnt != n)
45             printf(" ");
46         if(top->lchild != NULL) //左兒子入隊
47             Q.push(top->lchild);
48         if(top->rchild != NULL)//右兒子入隊
49             Q.push(top->rchild);
50     }
51 }
52 int main(){
53 
54     scanf("%d", &n);    //輸入結點數量
55     for(int i = 0; i < n; i++)  
56         scanf("%d", &postorder[i]); //輸入後序遍歷
57     for(int i = 0; i < n; i++)
58         scanf("%d", &inorder[i]);   //輸入中序遍歷
59     node *root = create(0, n - 1, 0, n - 1);    //建樹
60     levelorder(root);   //輸出層序遍歷
61     return 0;
62 }