• 王道书 P150 T12(打印x的所有祖先) + 拓展(打印从根节点到某个节点的路径、求根节点到某个节点的路径长度、求根节点的最大路径长度)


    1. /**
    2. * 用二叉树链式存储实现 王道 P150 T12(打印x的所有祖先)
    3. * + 拓展(打印从根节点到某个节点的路径、求根节点到某个节点的路径长度、求根节点的最大路径长度)
    4. *
    5. * ①算法思想
    6. * ①②③④都是非递归方式,除了④都是从非递归先序遍历改来的,
    7. * ④也可以说是从“求树高”的代码改来的,因为求根节点的最长路径,就相当于求某出个节点的最深层次,和求树高过程一样,
    8. * 求树高可以从层次和后序等改来的(参考P149 T5 文章).
    9. * ①②③他们的思维过程和遇到某个值时弹出栈里的元素是一样的。
    10. * ①打印x的所有祖先
    11. * ②打印从根节点到某个节点的路径
    12. * ③求根节点到某个节点的路径长度
    13. * ④求根节点的最大路径长度
    14. * ⑤求根节点的最长路径
    15. *
    16. * ②算法设计
    17. */
    18. #include <stdio.h>
    19. #include <iostream>
    20. #define MaxSize 100
    21. typedef struct BiTreeNode{
    22. int data;
    23. BiTreeNode *lchild,*rchild;
    24. }BiTreeNode,*BiTree;
    25. //P150 T12
    26. //①打印x节点的所有祖先
    27. void PrintPreByPreOrderNR(BiTree T,int x){
    28. BiTree stack[MaxSize],p = T;
    29. int top = -1,tag[MaxSize] = {0};
    30. while(p || top != -1){
    31. if(p){
    32. stack[++top] = p;
    33. tag[top] = 1;
    34. p = p -> lchild;
    35. }else{
    36. if(tag[top] == 1){
    37. tag[top] = 2;
    38. p = stack[top];
    39. p = p -> rchild;
    40. }else{//说明是叶子节点了
    41. p = stack[top--];
    42. // Visit(p);
    43. //打印祖先
    44. if(p -> data == x){
    45. for (int i = 0; i <= top ; ++i) {
    46. printf("%d ",stack[i] -> data);
    47. }
    48. }
    49. p = NULL;
    50. }
    51. }
    52. }
    53. }
    54. //②打印从根节点到某个节点的路径
    55. void PrintPathByPreOrderNR(BiTree T,int x){
    56. BiTree stack[MaxSize],p = T;
    57. int top = -1,tag[MaxSize] = {0};
    58. while(p || top != -1){
    59. if(p){
    60. stack[++top] = p;
    61. tag[top] = 1;
    62. p = p -> lchild;
    63. }else{
    64. if(tag[top] == 1){
    65. tag[top] = 2;
    66. p = stack[top];
    67. p = p -> rchild;
    68. }else{//说明是叶子节点了
    69. // p = stack[top--];
    70. //这边要把出栈放缓,不让就打印不出来了
    71. p = stack[top];
    72. // Visit(p);
    73. //打印路径
    74. if(p -> data == x){
    75. for (int i = 0; i <= top ; ++i) {
    76. printf("%d ",stack[i] -> data);
    77. }
    78. }
    79. //top--放这
    80. top--;
    81. p = NULL;
    82. }
    83. }
    84. }
    85. }
    86. //③求根节点到某个节点的路径长度
    87. int XPathLengthByPreOrderNR(BiTree T,int x){
    88. BiTree stack[MaxSize],p = T;
    89. int top = -1,tag[MaxSize] = {0};
    90. while(p || top != -1){
    91. if(p){
    92. stack[++top] = p;
    93. tag[top] = 1;
    94. p = p -> lchild;
    95. }else{
    96. if(tag[top] == 1){
    97. tag[top] = 2;
    98. p = stack[top];
    99. p = p -> rchild;
    100. }else{//说明是叶子节点了
    101. // p = stack[top--];
    102. //这边要把出栈放缓,不让就打印不出来了
    103. p = stack[top];
    104. // Visit(p);
    105. //打印路径长度
    106. if(p -> data == x){
    107. return top + 1;
    108. }
    109. //top--放这
    110. top--;
    111. p = NULL;
    112. }
    113. }
    114. }
    115. return -1;
    116. }
    117. //④求根节点的最大路径长度
    118. int GetMaxPathLength(BiTree T){
    119. BiTree stack[MaxSize],p = T;
    120. int top = -1,tag[MaxSize] = {0},max = -1;//max用来记录高度
    121. while(p || top != -1){
    122. if(p){
    123. stack[++top] = p;
    124. tag[top] = 1;
    125. p = p -> lchild;
    126. }else{
    127. if(tag[top] == 1){
    128. tag[top] = 2;
    129. p = stack[top];//找到栈顶元素,这样才能接着往下找
    130. p = p -> rchild;
    131. }else{//说明是叶子节点了
    132. p = stack[top];//访问这个点的时候先不急着出栈,因为如果直接出栈的话,高度就有损失了
    133. if(p -> lchild == NULL && p -> rchild == NULL){//说明是叶子节点
    134. if(top + 1 > max)//top是从-1开始的,或者说top是数组的下标,所以要+1才是路径的长度
    135. //注意这个top是一直在变化的,所以每遇到一个叶子节点,就要来比较一下,这样才能找到路径最长的叶子节点。
    136. max = top + 1;
    137. }
    138. top--;
    139. p = NULL;
    140. }
    141. }
    142. }
    143. return max;
    144. }
    145. //⑤求根节点的最长路径
    146. int GetMaxPathByPostOrder(BiTree T){
    147. BiTree stack[MaxSize],p = T;
    148. int top = -1,tag[MaxSize] = {0};
    149. int max = -1,path[MaxSize];
    150. while(p || top != -1){
    151. if(p){
    152. stack[++top] = p;
    153. tag[top] = 1;
    154. p = p -> lchild;
    155. }else{
    156. if(tag[top] == 1){
    157. tag[top] = 2;
    158. p = stack[top];
    159. p = p -> rchild;
    160. }else{//说明是叶子节点了
    161. p = stack[top];//放缓一步
    162. // Visit(p);
    163. if(p -> lchild == NULL && p -> rchild == NULL){
    164. if(top + 1 > max){
    165. max = top + 1;
    166. for (int i = 0; i < top; ++i) {
    167. path[i] = stack[i] -> data;
    168. }
    169. }
    170. }
    171. top--;
    172. p = NULL;
    173. }
    174. }
    175. }
    176. for (int i = 0; i < max ; ++i) {
    177. printf("%d ",path[i]);
    178. }
    179. return max;
    180. }

  • 相关阅读:
    [word] 如何在word中插入地图? #学习方法#其他
    Soul CEO张璐团队优化治理平台安全生态,构建健康社交秩序
    『第五章』二见痴心:初识小雨燕(中)
    k8s之Job和CronJob
    代码整洁之道-读书笔记之错误处理
    小白跟做江科大51单片机之DS1302可调时钟
    RK3588 DDR电源电路设计详解
    Android四大组件之- Service的创建与应用
    【Prism系列】Prism事件聚合器
    1704. 判断字符串的两半是否相似
  • 原文地址:https://blog.csdn.net/shengruyu/article/details/126609657