This is my very first.
哈哈,闲话少说,转入正题。
学完数据结构后,老是感觉学得不扎实,于是到MOOC网上去刷题。结果在Tree Traversal 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 key 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 can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of the tree. (关于题目的更详细的信息看这里http://www.patest.cn/contests/mooc-ds2015spring/03-%E6%A0%912)
当时没大弄明白这道题目的意思,几番纠结之后,我看了一下陈越老师的讲课视频,恍然大悟。如果给出一棵二叉树的先序遍历和中序遍历结果,那么这棵二叉树就唯一确定了。题目中给出的不就是先序遍历和中序遍历的结果吗?把入栈的过程记录下来就是先序遍历的结果,把出栈的过程记录下来就是中序遍历的结果。突然又想起来这种问题在严蔚敏老师的那本数据结构上讲过,时间一长,我竟然给忘了!翻书,果然找到了已知先序序列和中序序列如何求二叉树的方法。不过我们这里没有必要把二叉树求出来再进行后续遍历,只需按照后序遍历的顺序把元素放到数组的相应位置就可以了。下面是实现的代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 void get_post(int *pre, int *in, int *pt, int num); 6 7 int main() 8 { 9 int num; //the number of nodes 10 int data; 11 int i; 12 char opr[6]; 13 int *pre = NULL; //preorder 14 int *in = NULL; //inorder 15 int *post = NULL; //postorder 16 int *tmp = NULL; //a temporary array, used as a stack 17 int *pe; 18 int *pi; 19 int *pt; 20 int *pm; 21 scanf ("%d", &num); 22 pre = (int *)malloc(num*sizeof(int)); 23 in = (int *)malloc(num*sizeof(int)); 24 post = (int *)malloc(num*sizeof(int)); 25 tmp = (int *)malloc(num*sizeof(int)); 26 if (!pre||!in||!post||!tmp) 27 { 28 printf ("fail to allocate space!\n"); 29 exit (1); 30 } 31 pe = pre; 32 pi = in; 33 pt = post; 34 pm = tmp; 35 for (i=0; i<2*num; i++) 36 { 37 scanf ("%s", opr); 38 if (strcmp("Push", opr)==0) 39 {//the operation is push 40 scanf ("%d", &data); 41 *pe++ = data; 42 *pm++ = data; 43 } 44 else 45 {//the operation is pop 46 *pi++ = *--pm; 47 } 48 } 49 //get the postorder traversal sequence of binary tree; 50 pt += num-1; 51 get_post(pre, in, pt, num); 52 for (i=0; i<num; i++) 53 { 54 printf ("%d ", post[i]); 55 } 56 return 0; 57 } 58 59 void get_post(int *pre, int *in, int *pt, int num) 60 { 61 int i; 62 if (num==0) return; 63 for (i=0; i<num; i++) 64 { 65 if (in[i]==pre[0]) 66 break; 67 } 68 *pt = pre[0]; 69 get_post(pre+1, in, pt-(num-i), i); //get the postorder traversal sequence of left-child 70 get_post(pre+i+1, in+i+1, pt-1, num-i-1); //get the postorder traversal sequence of right-child 71 }