81.png

    1. /*
    2. p、q分别为指向该二叉树中任意两个节点的指针,试编写算法ancestor(root,p,q,r),找到p、q的最近公共祖先节点r
    3. 分析:
    4. 上一道题其实可以给我们一些启示,就是我们可以将任意节点的祖先存起来,那这里我们也可以用两个栈,分别将p、q
    5. 的祖先存在栈中,因为栈顶是最近的祖先节点,所以我们可以一次往下寻找相同节点,第一次找到的相同节点便是最近公共
    6. 祖先节点。
    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 findAncestor(Stack *s, biTree *m, biTree *x) {
    21. struct biTree *r = (struct biTree *)malloc(sizeof(struct biTree));
    22. bool empty(Stack *);
    23. bool push(Stack *, biTree*);
    24. bool pop(Stack *);
    25. biTree *top(Stack *);//返回得是一个指针
    26. while (m || !empty(s)) {
    27. if (m) {//一路将所有左孩子入栈
    28. push(s, m);
    29. m = m->lchild;
    30. }
    31. else {//没有左孩子,
    32. m = top(s);
    33. if (m->rchild&&r != m->rchild) {
    34. m = m->rchild;
    35. push(s, m);
    36. m = m->lchild;
    37. }
    38. else {//当既没有左孩子也没有右孩子时,该出栈了
    39. pop(s);//被查找元素先出栈
    40. if (m->data == x->data) {//找到了,那么如果栈中有元素,那全都是它的祖先
    41. break;
    42. }
    43. r = m;
    44. m = NULL;//一定要将p置空,不然又会把m的左孩子入栈
    45. }
    46. }
    47. }
    48. }
    49. void findNearestAncestor(biTree *T, biTree *p, biTree *q, biTree **r) {
    50. int count = 0;
    51. struct biTree *m = T;//另起指针m,指向根节点
    52. void nodeNum(biTree *, int *);
    53. nodeNum(T, &count);//统计节点个数
    54. struct Stack *sp, *sq;
    55. Stack *createStack(int);
    56. sp = createStack(count);
    57. sq = createStack(count);
    58. findAncestor(sp, m, p);//寻找p节点的祖先,放到栈中
    59. findAncestor(sq, m, q);//寻找q节点的祖先
    60. //经过上面的操作,栈sp和sq里面已经存好了p、q各自的祖先,接下来便是寻找最近祖先
    61. bool contain(Stack *,biTree *);
    62. bool empty(Stack *);
    63. bool push(Stack *, biTree*);
    64. bool pop(Stack *);
    65. biTree *top(Stack *);//返回得是一个指针
    66. while (!empty(sp)) {//当sp不空
    67. *r = top(sp);
    68. if (contain(sq,*r)) {//判断sq中知否包含d
    69. break;
    70. }
    71. pop(sp);
    72. }
    73. }
    74. int main() {
    75. int count = 0;
    76. struct biTree *T = (struct biTree *)malloc(sizeof(struct biTree)), *p, *q;
    77. struct biTree *r = (struct biTree *)malloc(sizeof(struct biTree));
    78. biTree *create(biTree *);
    79. T = create(T);
    80. p = T->lchild->lchild->rchild;//手动指定一个节点,切记不要指成NULL了
    81. q = T->rchild->rchild;
    82. //p = T->lchild;
    83. //q = T->rchild;
    84. findNearestAncestor(T, p, q, &r);//记得这里要将r的地址传过去,才能进行改变
    85. printf("p q最近公共结点为值为:%c",r->data);
    86. return 0;
    87. }