1. /*
    2. 试写出非递归的后序遍历算法
    3. 分析:
    4. 非递归的后续遍历较中序和先序而言,稍微复杂一点,首先我们需要一直从根节点往下寻找左孩子并入栈,之后访问栈顶元素,
    5. 并判断是否有右孩子,如果有右孩子入栈,并继续往左孩子找,直到某节点为单节点,出栈并访问。需要注意的是因为有可能一个节点我们
    6. 会访问多次,所以我们设置一个指针r用来表示上一次被访问过得节点
    7. */
    8. struct biTree {//树的结构体
    9. char data;
    10. struct biTree *lchild;
    11. struct biTree *rchild;
    12. };
    13. struct Stack {//栈的结构体
    14. biTree** arr; //内存首地址
    15. int len; //栈的容量
    16. int top; //栈的下标
    17. };
    18. #include <stdio.h>
    19. #include <stdlib.h>
    20. void postOrder(biTree *T, Stack *s) {//后序遍历
    21. biTree *p = T;
    22. biTree *r = (struct biTree*)malloc(sizeof(struct biTree));
    23. bool empty(Stack *);
    24. bool push(Stack *, biTree *);
    25. biTree *top(Stack *);
    26. bool pop(Stack *);
    27. while (p || !empty(s)) {
    28. if (p) {//一路向左
    29. push(s, p);
    30. p = p->lchild;
    31. }
    32. else {
    33. p = top(s);
    34. if (p->rchild&&r != p->rchild) {
    35. p = p->rchild;
    36. push(s, p);
    37. p = p->lchild;
    38. }
    39. else {
    40. printf("%c ", p->data);//打印栈顶元素
    41. r = p;
    42. pop(s);//栈顶元素出栈
    43. p = NULL;//这里一定要将p设为NULL,因为p的孩子已经遍历过了,不设置为NUll的话,又会将左孩子压入栈
    44. }
    45. }
    46. }
    47. }
    48. int main() {
    49. int count = 0;
    50. struct biTree *T = (struct biTree *)malloc(sizeof(struct biTree));
    51. struct Stack *s = (struct Stack*)malloc(sizeof(struct Stack));
    52. biTree *create(biTree*);
    53. void nodeNum(biTree *, int *);
    54. Stack *createStack(int);
    55. T = create(T);
    56. nodeNum(T, &count);
    57. s = createStack(count);//创建二叉树节点个数大小的栈
    58. postOrder(T, s);
    59. return 0;
    60. }