当前位置:   article > 正文

数据结构:线索二叉树_二叉树cpp文件

二叉树cpp文件

目录

        1.线索二叉树是什么?

        2.包含头文件

        3.结点设计

        4.接口函数定义

        5.接口函数实现


线索二叉树是什么?

        线索二叉树(Threaded Binary Tree)是一种对普通二叉树的扩展,它通过在树的某些空指针上添加线索来实现更高效的遍历操作。线索二叉树的目的是减少查找特定节点(如前驱或后继节点)所需的时间,从而提高树的搜索效率。以下是线索二叉树的特点:

        1.普通二叉树的扩展:线索二叉树是基于普通二叉树的,它保留了二叉树的所有性质。

        2.线索:在二叉树的空指针(左子树或右子树的指针)上添加线索,这些线索可以指导我们找到节点的前驱或后继。

        3.前驱和后继:每个节点的前驱是其在中序遍历中直接前的一个节点,后继是直接后的节点。线索二叉树允许我们通过线索快速找到这些节点。


包含头文件

  1. #include<stdio.h>
  2. #include<stdlib.h>

结点设计

  1. #define Initsize 100
  2. typedef char Elemtype;
  3. typedef struct ThreadTree {
  4. Elemtype data; //定义Elemtype类型的变量存储结点值
  5. struct ThreadTree* lchild; //定义ThreadTree类型的指针变量lchild存储左子树的地址
  6. struct ThreadTree* rchild; //定义ThreadTree类型的指针变量rchild存储右子树的地址
  7. int Lvalue, Rvalue; //定义int类型的变量Lvalue和Rvalue分别标识线索
  8. }ThreadTree,* ThTree;
  9. ThTree Pre = NULL; //定义ThTree类型的全局变量Pre指向此次结点的前驱结点

接口函数定义

  1. void InitThTree(ThTree& A); //用于初始化线索二叉树
  2. void InsertTree(ThTree& A); //用于输入数据建立二叉树
  3. void InOrder(ThTree A); //用于在二叉树中执行中序遍历
  4. void InOrderVisit(ThTree& A); //用于在结点中进行中序线索化
  5. void InOrderThread(ThTree& A); //用于中序遍历线索化二叉树
  6. void PreOrder(ThTree A); //用于在二叉树中执行先序遍历
  7. void PreOrderVisit(ThTree& A); //用于先序遍历线索化二叉树
  8. void PreOrderThread(ThTree& A); //用于先序遍历线索化二叉树
  9. void PostOrder(ThTree A); //用于执行后序遍历
  10. void PostOrderVisit(ThTree& A); //用于后序遍历线索化二叉树
  11. void PostOrderThread(ThTree& A); //用于后序遍历线索化二叉树

接口函数实现

  1. void PostOrderThread(ThTree& A) { //用于后序遍历线索化二叉树
  2. Pre = NULL;
  3. if (A != NULL) {
  4. PostOrder(A);
  5. if (A->rchild == NULL){
  6. Pre->Rvalue = 1;
  7. }
  8. }
  9. }
  10. void PostOrderVisit(ThTree& A) { //用于后序遍历线索化二叉树
  11. if (A->lchild == NULL) { //若传入的结点的左子树为空,则将该结点的左子树线索化
  12. A->Lvalue = 1;
  13. A->lchild = Pre;
  14. }
  15. if (A->rchild == NULL && Pre != NULL) {
  16. //若传入的结点的空子树为空,且前驱结点不为空,则将该结点的左子树线索化
  17. Pre->rchild = A;
  18. Pre->Rvalue = 1;
  19. }
  20. Pre = A;
  21. }
  22. void PostOrder(ThTree A) { //用于执行后序遍历
  23. if (A != NULL) {
  24. PostOrder(A->lchild);
  25. PostOrder(A->rchild);
  26. PostOrderVisit(A);
  27. }
  28. }
  29. void PreOrderThread(ThTree& A) { //用于先序遍历线索化二叉树
  30. Pre = NULL;
  31. if (A != NULL) {
  32. PreOrder(A);
  33. if (Pre->rchild == NULL) {
  34. Pre->Rvalue = 1;
  35. }
  36. }
  37. }
  38. void PreOrderVisit(ThTree& A) { //用于先序遍历线索化二叉树
  39. if (A->lchild == NULL) { //若传入的结点的左子树为空,则将该结点的左子树线索化
  40. A->Lvalue = 1;
  41. A->lchild = Pre;
  42. }
  43. if (A->rchild == NULL && Pre != NULL) {
  44. //若传入的结点的空子树为空,且前驱结点不为空,则将该结点的左子树线索化
  45. Pre->Rvalue = 1;
  46. Pre->rchild = A;
  47. }
  48. Pre = A;
  49. }
  50. void PreOrder(ThTree A) { //用于在二叉树中执行先序遍历
  51. if (A != NULL) {
  52. PreOrderVisit(A);
  53. if (A->Lvalue==0) {
  54. PreOrder(A->lchild);
  55. }
  56. PreOrder(A->rchild);
  57. }
  58. }
  59. void InOrderThread(ThTree& A) { //用于中序遍历线索化二叉树
  60. Pre = NULL; //遍历第一个结点时,第一个结点无前驱结点,故Pre为NULL
  61. if (A != NULL) {
  62. InOrder(A); //进行中序遍历
  63. if (Pre->rchild == NULL) { //将中序遍历的最后一个结点的右子树线索化
  64. Pre->Rvalue = 1; //因为其结点无后继,故不更新指向
  65. }
  66. }
  67. }
  68. void InOrderVisit(ThTree& A) { //用于在结点中进行线索化
  69. if (A->lchild == NULL) { //左子树若为空,则将其左子树线索化
  70. A->Lvalue = 1;
  71. A->lchild = Pre;
  72. }
  73. if (A->rchild == NULL && Pre != NULL) {//右子树若为空,则将其右子树线索化
  74. Pre->rchild = A;
  75. Pre->Rvalue = 1;
  76. }
  77. Pre = A; //更新指向前驱结点的指针pre
  78. }
  79. void InOrder(ThTree A) { //用于在二叉树执行中序遍历
  80. if (A!= NULL) {
  81. InOrder(A->lchild);
  82. InOrderVisit(A);
  83. InOrder(A->rchild);
  84. }
  85. }
  86. void InsertTree(ThTree& A) { //用于输入数据建立二叉树
  87. ThTree Q[Initsize], //定义ThTree类型的指针数组存储根结点的地址
  88. W = NULL; //定义Thtree类型的指针W指向新建的结点的地址
  89. int i=0, //定义int类型的变量i作为左右孩子树的标识
  90. j=0, //定义int类型的变量j作为字符串遍历的指针
  91. top=-1; //定义int类型的变量top作为结点数组的指针
  92. char E,R[Initsize];
  93. printf("请以括号法输入数据,并以此建立二叉树:");
  94. scanf_s("%s", R, Initsize);
  95. E = R[i];
  96. while (E != '\0') {
  97. switch (E) {
  98. case '(':
  99. top++; //入栈操作
  100. Q[top] = W;
  101. i = 1; //对新结点做标识,1为左子树的标识
  102. break;
  103. case ',':
  104. i = 2; //对新结点做标识,2为右子树的标识
  105. break;
  106. case ')':
  107. top--; //出栈操作
  108. break;
  109. default:
  110. W = (ThreadTree*)malloc(sizeof(ThreadTree)); //新建结点
  111. W->data = E; //更新结点的数据域data的指向
  112. W->rchild = W->lchild = NULL;
  113. if (A == NULL) { //当传入的结点为空时,则新建的结点为树的根结点
  114. A = W;
  115. }
  116. else {
  117. switch (i) { //判断传入的结点为左子树还是右子树
  118. case 1:
  119. Q[top]->lchild = W; //将栈内的根结点的lchild指向新建的地址
  120. break;
  121. case 2:
  122. Q[top]->rchild = W; //将栈内的根结点的rchild指向新建的地址
  123. break;
  124. }
  125. }
  126. }
  127. j++;
  128. E = R[j];
  129. }
  130. printf("构建线索二叉树对应的二叉树成功\n");
  131. }
  132. void InitThTree(ThTree& A) { //用于初始化线索二叉树
  133. A = NULL;
  134. printf("初始化线索二叉树成功\n");
  135. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/700955
推荐阅读
相关标签
  

闽ICP备14008679号