数据结构:线索二叉树

打印 上一主题 下一主题

主题 698|帖子 698|积分 2094

目录
        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. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莫张周刘王

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表