后续遍历关键在于,当节点的 右子树存在且被访问后 或者是 右子树为空 才能访问自身。
在遍历过程中,先将节点从的左孩子到最左节点压栈, 设置标志变量 flag 来判断是否访问过左孩子, pre指针来指向先前访问过的节点。
所有左孩子压栈后, 最后一个节点的左孩子为空,已被访问p = NULL , 令flag=1
当左孩子被访问时,进入循环,取栈顶节点。
1. 当栈顶节点的右孩子 等于 空 或 前一个被访问的节点 时, 访问该节点, 令pre 等于当前节点,pre = p, 当前节点出栈。
2. 当栈顶节点的右孩子不为空时, 继续遍历以右孩子为根节点的右子树。
1 Status PostOrderTraverse(BiTree T){ 2 BiTree p = T, S[100], pre; 3 int top = 0, flag = 1; 4 if(p) 5 do{ 6 while(p){ 7 S[top++] = p; 8 p = p->lchild; 9 } 10 // p所有左节点入栈 11 flag = 1; 12 13 while(top != 0 && flag == 1){ 14 p = S[top-1]; 15 if(p->rchild == pre || p->rchild == NULL){ 16 //右孩子不存在或右孩子已访问 17 top--; 18 printf("%c ", p->data); 19 pre = p; 20 //指向被访问节点 21 } 22 else{ 23 //继续遍历右子树 24 p = p->rchild; 25 flag = 0; 26 } 27 } 28 }while(top != 0); 29 return OK; 30 }//PostOrderTraverse
完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define TElemType char 5 #define Status int 6 #define OK 1 7 8 typedef struct BiTNode{ 9 TElemType data; 10 struct BiTNode *lchild, *rchild; 11 }BiTNode, *BiTree; 12 13 Status CreateBiTree(BiTree &T){ 14 TElemType ch = getchar(); 15 if(ch == '#') T = NULL; 16 else{ 17 T = (BiTree)malloc(sizeof(BiTNode)); 18 T->data = ch; 19 CreateBiTree(T->lchild); 20 CreateBiTree(T->rchild); 21 } 22 return OK; 23 }//CreateBiTree 24 25 Status PostOrderTraverse(BiTree T){ 26 BiTree p = T, S[100], pre=NULL; 27 int top = 0, flag = 1; 28 if(p) 29 do{ 30 while(p){ 31 S[top++] = p; 32 p = p->lchild; 33 } 34 35 flag = 1; 36 37 while(top != 0 && flag == 1){ 38 p = S[top-1]; 39 if(p->rchild == pre || p->rchild == NULL){ 40 top--; 41 printf("%c ", p->data); 42 pre = p; 43 } 44 else{ 45 p = p->rchild; 46 flag = 0; 47 } 48 } 49 }while(top != 0); 50 return OK; 51 }//PostOrderTraverse 52 53 int main(){ 54 BiTree T; 55 CreateBiTree(T); 56 PostOrderTraverse(T); 57 return 0; 58 }