当前位置:   article > 正文

(数据结构)二叉树后序遍历_求二叉树的后序遍历

求二叉树的后序遍历

二叉树后序遍历

二叉树后序遍历的实现思想是:

  1. 访问当前节点的左子树
  2. 访问当前节点的右子树
  3. 访问根节点

图 1 二叉树

以上图 1 为例,后序遍历的过程如下:

  1. 从根节点 1 开始,遍历该节点的左子树(以节点 2 为根节点)
  2. 遍历节点 2 的左子树(以节点 4 为根节点)
  3. 由于节点 4 既没有左子树,也没有右子树,此时访问该节点中的元素 4,并回退到节点 2 ,遍历节点 2 的右子树(以 5 为根节点)
  4. 由于节点 5 无左右子树,因此可以访问节点 5 ,并且此时节点 2 的左右子树也遍历完成,因此也可以访问节点 2
  5. 此时回退到节点 1 ,开始遍历节点 1 的右子树(以节点 3 为根节点)
  6. 遍历节点 3 的左子树(以节点 6 为根节点)
  7. 由于节点 6 无左右子树,因此访问节点 6,并回退到节点 3,开始遍历节点 3 的右子树(以节点 7 为根节点)
  8. 由于节点 7 无左右子树,因此访问节点 7,并且节点 3 的左右子树也遍历完成,可以访问节点 3;节点 1 的左右子树也遍历完成,可以访问节点 1

因此,图 1 中二叉树采用中序遍历得到的序列为:4 5 2 6 7 3 1

二叉树后序遍历代码实现

先谈一下递归实现!!!

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct MyBiTNode{
  4. int data; // 数据域
  5. struct MyBiTNode *lchild, *rchild; // 左右孩子指针
  6. } BiTNode;
  7. BiTNode *CreateBiTree(BiTNode *T){
  8. // 结点 1
  9. T = (BiTNode*)malloc(sizeof(BiTNode));
  10. T->data = 1;
  11. // 结点 2
  12. T->lchild = (BiTNode*)malloc(sizeof(BiTNode));
  13. T->lchild->data = 2;
  14. // 结点 3
  15. T->rchild = (BiTNode*)malloc(sizeof(BiTNode));
  16. T->rchild->data = 3;
  17. // 结点 4
  18. T->lchild->lchild = (BiTNode*)malloc(sizeof(BiTNode));
  19. T->lchild->lchild->data = 4;
  20. T->lchild->lchild->lchild = NULL;
  21. T->lchild->lchild->rchild = NULL;
  22. // 结点 5
  23. T->lchild->rchild = (BiTNode*)malloc(sizeof(BiTNode));
  24. T->lchild->rchild->data = 5;
  25. T->lchild->rchild->lchild = NULL;
  26. T->lchild->rchild->rchild = NULL;
  27. // 结点 6
  28. T->rchild->lchild = (BiTNode*)malloc(sizeof(BiTNode));
  29. T->rchild->lchild->data = 6;
  30. T->rchild->lchild->lchild = NULL;
  31. T->rchild->lchild->rchild = NULL;
  32. // 结点 7
  33. T->rchild->rchild = (BiTNode*)malloc(sizeof(BiTNode));
  34. T->rchild->rchild->data = 7;
  35. T->rchild->rchild->lchild = NULL;
  36. T->rchild->rchild->rchild = NULL;
  37. return T;
  38. }
  39. // 模拟操作结点元素的函数,输出结点本身的数值
  40. void displayElem(BiTNode* elem){
  41. printf("%d ", elem->data);
  42. }
  43. // 后序遍历
  44. void PostOrderTraverse(BiTNode *T){
  45. if(T){
  46. PostOrderTraverse(T->lchild); // 遍历左孩子
  47. PostOrderTraverse(T->rchild); // 遍历右孩子
  48. displayElem(T); // 调用操作结点数据的函数方法
  49. }
  50. // 如果结点为空,返回上一层
  51. return;
  52. }
  53. int main() {
  54. BiTNode *Tree = NULL; // 结构体指针指向空
  55. Tree = CreateBiTree(Tree); // 传入结构体指针
  56. printf("%d\n",Tree->rchild->lchild->data); // 4
  57. PostOrderTraverse(Tree);
  58. return 0;
  59. }

再谈一下非递归实现!!!

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int top = -1; // top变量表示栈顶元素所在位置
  4. typedef struct MyBiTNode{
  5. int data; // 数据域
  6. struct MyBiTNode *lchild, *rchild; // 左右孩子指针
  7. } BiTNode;
  8. BiTNode *CreateBiTree(BiTNode *T){
  9. // 结点 1
  10. T = (BiTNode*)malloc(sizeof(BiTNode));
  11. T->data = 1;
  12. // 结点 2
  13. T->lchild = (BiTNode*)malloc(sizeof(BiTNode));
  14. T->lchild->data = 2;
  15. // 结点 3
  16. T->rchild = (BiTNode*)malloc(sizeof(BiTNode));
  17. T->rchild->data = 3;
  18. // 结点 4
  19. T->lchild->lchild = (BiTNode*)malloc(sizeof(BiTNode));
  20. T->lchild->lchild->data = 4;
  21. T->lchild->lchild->lchild = NULL;
  22. T->lchild->lchild->rchild = NULL;
  23. // 结点 5
  24. T->lchild->rchild = (BiTNode*)malloc(sizeof(BiTNode));
  25. T->lchild->rchild->data = 5;
  26. T->lchild->rchild->lchild = NULL;
  27. T->lchild->rchild->rchild = NULL;
  28. // 结点 6
  29. T->rchild->lchild = (BiTNode*)malloc(sizeof(BiTNode));
  30. T->rchild->lchild->data = 6;
  31. T->rchild->lchild->lchild = NULL;
  32. T->rchild->lchild->rchild = NULL;
  33. // 结点 7
  34. T->rchild->rchild = (BiTNode*)malloc(sizeof(BiTNode));
  35. T->rchild->rchild->data = 7;
  36. T->rchild->rchild->lchild = NULL;
  37. T->rchild->rchild->rchild = NULL;
  38. return T;
  39. }
  40. // 模拟操作结点元素的函数,输出结点本身的数值
  41. void displayElem(BiTNode* elem){
  42. printf("%d ", elem->data);
  43. }
  44. // 弹栈函数
  45. void pop(){
  46. if(top == -1){
  47. return;
  48. }
  49. top--;
  50. }
  51. // 后序遍历非递归算法
  52. typedef struct SNode{
  53. BiTNode *p;
  54. int tag;
  55. } SNode;
  56. // 后序遍历使用的进栈函数
  57. void postpush(SNode *a, SNode sdata){
  58. a[++top] = sdata;
  59. }
  60. // 后序遍历函数
  61. void PostOrderTraverse(BiTNode *Tree){
  62. SNode a[20];
  63. BiTNode *p;
  64. int tag;
  65. SNode sdata;
  66. p = Tree; // 根结点
  67. while(p || top!=-1) {
  68. while(p){
  69. sdata.p = p;
  70. sdata.tag = 0;
  71. postpush(a, sdata);
  72. // a[0] = {Tree, 0};a[1] = {Tree->lchild, 0};a[2] = {Tree->lchild->lchild, 0}
  73. // a[2] = {Tree->lchild->rchild, 0}
  74. p = p->lchild; // 指向左结点
  75. }
  76. sdata = a[top];
  77. // sadta = a[2] = {Tree->lchild->lchild, 0} -- 4
  78. // sadta = a[2] = {Tree->lchild->lchild, 1} -- 4
  79. // sadta = a[1] = {Tree->lchild, 0} -- 2
  80. // sadta = a[2] = {Tree->lchild->rchild, 0} -- 5
  81. pop(); // top == 1; top == 1; top == 0; top == 1
  82. p = sdata.p; // Tree->lchild->lchild;Tree->lchild->lchild;Tree->lchild;Tree->lchild->rchild
  83. tag = sdata.tag; // 0 1 0 0
  84. if(tag == 0) {
  85. sdata.p = p; // Tree->lchild->lchild;Tree->lchild
  86. sdata.tag = 1; // 1 1
  87. postpush(a, sdata); // a[2] = {Tree->lchild->lchild, 1};a[1] = {Tree->lchild, 1}
  88. p = p->rchild; // NULL Tree->lchild->rchild
  89. }else{
  90. displayElem(p); // 4
  91. p = NULL;
  92. }
  93. }
  94. }
  95. int main() {
  96. BiTNode *Tree = NULL; // 结构体指针指向空
  97. Tree = CreateBiTree(Tree); // 传入结构体指针
  98. printf("%d\n",Tree->rchild->lchild->data); // 4
  99. PostOrderTraverse(Tree);
  100. return 0;
  101. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/758038
推荐阅读
相关标签
  

闽ICP备14008679号