03-树3 Tree Traversals Again

 
An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.

Figure 1

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; or "Pop" meaning to pop one node from the stack.

Output Specification:

For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

Sample Output:

3 4 2 6 5 1

 1 //Push的顺序是先序遍历的顺序,Pop的顺序的中序遍历的顺序
 2 //三个序列中,知道中序和随意另一个,即可确定一棵树 
 3 #include<stdio.h> 
 4 #include<stdlib.h>
 5 #define null -1
 6 
 7 struct SNode{
 8     int *Data;
 9     int Top;
10     int Maxsize; 
11 };
12 typedef struct SNode *stack;
13 
14 //建空堆栈 
15 stack BuildStack(int n){
16     stack S = (stack)malloc(sizeof(struct SNode));
17     S->Data = (int*)malloc(sizeof(int)*n);
18     S->Top = null;
19     S->Maxsize = n;
20     return S;
21 } 
22 
23 //判断堆栈是否满 
24 bool IsFull(stack S){
25     return S->Top == S->Maxsize-1;
26 }
27 
28 //将元素入栈 
29 void Push(stack S, int data){
30     if(!IsFull(S)){
31         S->Data[++(S->Top)] = data;
32     }
33 }
34 
35 //将元素出栈,没有写判断栈空的函数,这题不会超出堆栈范围的,其实判断栈满的函数也不用写(当然这样的习惯不好🤐)
36 int Pop(stack S){
37     return S->Data[(S->Top--)];
38 }
39 
40 //递归求后序序列 
41 void Posttraversal(int *pre, int *mid, int root, int left, int right) {
42      //root是pre中根节点的位置,left、right是这段序列在mid中的范围 
43      //这段写的很难看,可是我也不知道怎么改好一点,我知道了会回来改的🙃 
44     if(left>right){                   
45         return;
46     }
47     else if(left==right){            
48         printf("%d ", mid[left]);
49         return;
50     }
51     int i, L=0;
52     for(i=left; i<=right; i++){        //在mid中找到根的位置,以此确定左右子树 
53         if(mid[i]==pre[root]){
54             break;
55         }
56     }
57     L = i-left;      //求出左子树的个数,用这个去求递归右子树时pre中根节点的位置,将左子树为空的情况考虑进去 
58     Posttraversal(pre, mid, root+1, left, i-1);       //递归遍历左子树 
59     Posttraversal(pre, mid, root+L+1, i+1, right);    //递归遍历右子树 
60     if(root == 0) 
61         printf("%d\n", pre[0]);         //后序序列整棵树的根结点在最后,单独拿出来处理格式 
62     else 
63         printf("%d ", pre[root]);      
64 }
65 
66 int main( ){
67     int N;
68     scanf("%d", &N);
69     int data, pre[N], mid[N];
70     stack S = BuildStack(N);
71     for(int i=0, j=0, k=0; i<2*N; i++){
72         char c, str[5];
73         scanf("\n");
74         for(int m=0; m<5; m++){
75             scanf("%c", &c);
76             if(c=='\n')
77                 break;
78             else str[m] = c;
79         }
80         if(str[1]=='u'){
81             scanf("%d", &data);
82             pre[j++] = data;
83             Push(S, data);
84         }
85         else if(str[1]=='o'){
86             mid[k++] = Pop(S);
87         }
88     }
89 //    for(int i=0; i<N; i++) {
90 //        printf("%d %d\n", pre[i], mid[i]);
91 //    }
92     if(N==1) 
93         printf("%d\n", pre[0]);
94     else
95         Posttraversal(pre, mid, 0, 0, N-1);
96     return 0;
97 }

 

 
posted @ 2018-10-31 00:43  shenqingping  阅读(151)  评论(0)    收藏  举报