89.png

    1. /*
    2. 在二叉树中查找值为x的节点,试编写算法打印值为x的节点的所有祖先,假设x的值不多于一个。
    3. 分析:
    4. 这里我们采用后序遍历(非递归),因为在我们遇到x之前我们会把它的祖先节点全部入栈,当我们找到x时,再依次取出栈中元素
    5. */
    6. struct biTree {
    7. char data;
    8. struct biTree *lchild;
    9. struct biTree *rchild;
    10. };
    11. struct Stack {
    12. biTree *arr;
    13. int len;
    14. int top;
    15. };
    16. #include <stdio.h>
    17. #include <stdlib.h>
    18. void findAllAncestor(biTree *T, Stack *s, char x) {
    19. struct biTree *p = T;
    20. struct biTree *r = (struct biTree *)malloc(sizeof(struct biTree));
    21. struct biTree *tp = (struct biTree *)malloc(sizeof(struct biTree));
    22. bool push(Stack *, biTree*);
    23. bool pop(Stack *);
    24. biTree *top(Stack *);//返回得是一个指针
    25. bool empty(Stack *);
    26. while (p || !empty(s)) {
    27. if (p) {//一路将所有左孩子入栈
    28. push(s, p);
    29. p = p->lchild;
    30. }
    31. else {//没有左孩子,
    32. p = top(s);
    33. if (p->rchild && p != r) {//将右子树的所有左孩子入栈
    34. r = p;
    35. p = p->rchild;
    36. }
    37. else {//当既没有左孩子也没有右孩子时,该出栈了
    38. pop(s);//被查找元素先出栈
    39. if (p->data == x) {//找到了,那么如果栈中有元素,那全都是它的祖先
    40. printf("祖先元素有:");
    41. while (!empty(s)) {
    42. tp = top(s);
    43. printf("%c ", tp->data);
    44. pop(s);
    45. }
    46. }
    47. p = NULL;//一定要将p置空,不然又会把p的左孩子入栈
    48. }
    49. }
    50. }
    51. }
    52. int main() {
    53. int count = 0, x;
    54. struct biTree *T = (struct biTree *)malloc(sizeof(struct biTree));
    55. struct Stack *s;
    56. biTree *create(biTree *);
    57. void nodeNum(biTree *, int *);
    58. Stack *createStack(int);
    59. T = create(T);
    60. nodeNum(T, &count);
    61. s = createStack(count);
    62. printf("请输入要查找的元素:x=");
    63. x = getchar();
    64. findAllAncestor(T, s, x);
    65. return 0;
    66. }