zoukankan      html  css  js  c++  java
  • 线索二叉树

    线索二叉树就是让一些浪费的空间利用起来,并且获得效率。

    总体思路就是:中序遍历线索化,这样可以让空间利用率最大,建立一个指针p始终指向头结点,还有一个指针pre(全局变量)指向当前结点的上一个结点,因为要线索化,所以我们得让整棵树串联起来,例如图中的这棵树,中序遍历就是CBDAEF,加红的部分就是该结点有空间可以利用的,因为加红的结点都是左右两边指针都是NULL,或者一边是NULL,所以我们可以让左右两边分别设置两个指针,ltag,rtag(这两个指针都是枚举类型)表示左右两边是指向孩子,还是线索,有孩子就设为Link即为0,没有孩子就设为Thread即为1,同时根据中序遍历来使得结点线索化,就是让c的左指针指向头指针,右指针指向B,D的左指针指向B,右指针指向A,以此类推,实现线索化,最后不要忘了收尾工作,即图的最右边那两条线,在代码中有注释,最后当我们遍历打印的时候就可以根据,ltag,rtag的值进行判断,然后用迭代的方式打印即可。

    代码+注释:

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 
      4 typedef char ElemType;
      5 
      6 //线索存储标志位
      7 //Link(0)表示指向左右孩子的指针
      8 //Thread(1)表示指向前驱后继的线索
      9 typedef enum{Link,Thread} PointerTag;
     10 
     11 typedef struct BiThrNode
     12 {
     13     char data;
     14     struct BiThrNode* lchild, * rchild;
     15     PointerTag ltag;
     16     PointerTag rtag;
     17 }BiThrNode, * BiThrTree;
     18 
     19 //全局变量,始终指向刚刚访问过的结点
     20 BiThrTree pre;
     21 
     22 //前序遍历创建一颗二叉树
     23 void CreatBiThrTree(BiThrTree *T)
     24 {
     25     char c;
     26 
     27     scanf("%c", &c);
     28     if (' ' == c)
     29     {
     30         *T = NULL;
     31     }
     32     else
     33     {
     34         *T = (BiThrNode *)malloc(sizeof(BiThrNode));
     35         (*T)->data = c;
     36         (*T)->ltag = Link;
     37         (*T)->rtag = Link;
     38 
     39         CreatBiThrTree(&(*T)->lchild);
     40         CreatBiThrTree(&(*T)->rchild);
     41     }
     42 }
     43 
     44 //中序遍历线索化
     45 void InThreading(BiThrTree T) //pre是一个跟踪结点 不断地指向当前结点的前一个结点
     46 {
     47     if (T)
     48     {
     49         InThreading(T->lchild);  //递归左孩子线索化
     50 
     51         if (!T->lchild)  //如果该结点没有左孩子,设置ltag为Thread,并把lchild指向前驱
     52         {
     53             T->ltag = Thread;
     54             T->lchild = pre;
     55         }
     56 
     57         if (!pre->rchild)  //前驱结点没有有孩子,就把rtag = Thread,有孩子指向当前结点
     58         {
     59             pre->rtag = Thread;
     60             pre->rchild = T;
     61         }
     62 
     63         pre = T;
     64 
     65         InThreading(T->rchild); //递归右孩子线索化
     66     }
     67 }
     68 
     69 void InOrderThreading(BiThrTree *p,BiThrTree T)  //建立一个头指针
     70 {
     71     *p = (BiThrTree)malloc(sizeof(BiThrNode));
     72     (*p)->ltag = Link;
     73     (*p)->rtag = Thread;
     74     (*p)->rchild = *p;
     75     if (!T) //如果是空树
     76     {
     77         (*p)->lchild = *p;
     78     }
     79     else
     80     {
     81         (*p)->lchild = T;  //指向树的头结点
     82         pre = *p;
     83 
     84         InThreading(T);//线索化
     85         pre->rchild = *p; //收尾工作
     86         pre->rtag = Thread;
     87         (*p)->rchild = pre;
     88     }
     89 }
     90 
     91 void visit(char c)
     92 {
     93     printf("%c", c);
     94 }
     95 
     96 //中序遍历二叉树,非递归
     97 void InOrderTraverse(BiThrTree T)  
     98 {
     99     BiThrTree p; //p表示当前结点 T表示头指针
    100     p = T->lchild;
    101 
    102     while (p != T)
    103     {
    104         while (p->ltag == Link)
    105         {
    106             p = p->lchild;
    107         }
    108 
    109         visit(p->data);
    110 
    111         while (p->rtag == Thread && p->rchild != T)
    112         {
    113             p = p->rchild;
    114             visit(p->data);
    115         }
    116         p = p->rchild;
    117     }
    118 }
    119 
    120 int main()
    121 {
    122     BiThrTree P,T = NULL;  //P是指向头结点的头指针
    123 
    124     CreatBiThrTree(&T);
    125 
    126     InOrderThreading(&P,T);
    127 
    128     printf("中序遍历输出结果为: ");
    129     InOrderTraverse(P);
    130     return 0;
    131 }
  • 相关阅读:
    006_02SQLite_OpenHelper
    006_01SQLite_demo
    005_01XML_Serilizer
    004_05PullParser
    004_04SharedPreferences
    004_02文件读写模式
    004_01获取SD容量
    003_01电话拨号器
    maven项目中的pom.xml
    ORACLE提示表名无效
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/12680920.html
Copyright © 2011-2022 走看看