• 线索二叉树


    可学习的博客:

    http://blog.csdn.net/m6830098/article/details/8707814

    http://book.51cto.com/art/200907/134532.htm  

    http://www.lxway.com/6084102.htm                        

    http://www.ihypo.net/854.html                          

    https://pjf.name/post-127.html

    实现代码:

      1 //线索二叉树,这里在二叉树的基础上添加了线索化
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 typedef char ElemType;                     
      5 typedef enum {Link,Thread} childTag;     //Link表示结点,Thread表示线索
      6 typedef struct bitNode
      7 {
      8   ElemType data;
      9   struct bitNode *lchild, *rchild;
     10   int ltag, rtag;
     11 } bitNode, *bitTree;
     12 
     13 bitTree pre;                             //创建全局变量,表示刚刚访问过的结点
     14 
     15 
     16 
     17 /*
     18 创建二叉树,其输入必须按照前序遍历的次序。
     19 T:二叉树根节点
     20 arr:按照前序遍历次序排列的各节点的值。无孩子结点时用空格代替
     21 */
     22 void create_tree(bitTree *T, char **arr)
     23 {
     24   char c;
     25   sscanf(*arr,"%c",&c);                         //读入一个结点值
     26   (*arr)++;
     27   if(' '== c)                                     //如果是空格,表示空结点
     28     {
     29       *T=NULL;
     30     }
     31   else 
     32     {
     33       *T=(bitTree)malloc(sizeof(bitNode));         //构造新结点
     34       (*T)->data=c;
     35       (*T)->ltag=Link;
     36       (*T)->rtag=Link;
     37       create_tree(&(*T)->lchild,arr);            //构造新结点的左孩子
     38       create_tree(&(*T)->rchild,arr);            //构造新结点的右孩子
     39     }
     40 }
     41 
     42 
     43 /*
     44 访问结点信息
     45 */
     46 void visit(bitTree T)
     47 {
     48     printf("| %d | %c | %d |
    ",T->ltag,T->data,T->rtag);
     49 }
     50 
     51 
     52 /*
     53 前序遍历访问二叉树
     54 */
     55 void pre_order_traverse(bitTree T,int level)
     56 {
     57   if(T)
     58     {
     59       visit(T);
     60       pre_order_traverse(T->lchild,level+1);
     61       pre_order_traverse(T->rchild,level+1);
     62     }
     63 }
     64 
     65 /*
     66 中序遍历二叉树,对其进行线索化
     67 */
     68 void in_order_threading(bitTree T)
     69 {
     70   if(T)
     71     {
     72       in_order_threading(T->lchild);             //左孩子线索化
     73       if(!T->lchild)                             //如果左孩子为空,则将其指向直接前驱
     74     {
     75       T->lchild=pre;
     76       T->ltag=Thread;
     77     }
     78       if(!pre->rchild)                             //如果上一个结点的右孩子为空,则将其指向直接后继。(注意:只有访问到下一个结点时,才会知道本结点的后继是谁)
     79     {
     80       pre->rchild=T;
     81       pre->rtag=Thread;
     82     }
     83       pre=T;
     84       in_order_threading(T->rchild);             //右孩子线索化
     85     }
     86 }
     87 
     88 /*
     89 加入一个头结点,使二叉线索树成一个封闭环
     90 P:带有头结点的二叉树。头结点的左孩子指向二叉树T;右孩子指向T树中的最后一个叶子结点
     91 T:不带有头结点的二叉树。
     92 */
     93 void in_thread(bitTree *P,bitTree T)
     94 {
     95   (*P)=(bitTree)malloc(sizeof(bitNode));         //构造新加入的头结点
     96   (*P)->ltag=Link;
     97   (*P)->rtag=Thread;
     98   (*P)->rchild=*P;
     99   if(!T)                                         //如果二叉树为空,则P的孩子指向自己。
    100     {
    101       (*P)->lchild=*P;
    102     }
    103   else
    104     {
    105       (*P)->lchild=T;
    106       pre=*P;
    107       in_order_threading(T);                     //对二叉树进行线索化
    108       (*P)->rchild=pre;                         //将头结点右孩子指向最后一个叶子结点
    109       pre->rtag=Thread;                         //将最后一个叶子结点的右孩子指向头结点。这样,环就形成了。
    110       pre->rchild=*P;
    111     }
    112 }
    113 
    114 /*
    115 非递归方式:中序遍历二叉树(树必须带有头结点,且已经线索化)
    116 P:带有头结点的二叉树
    117 */
    118 void in_order_traverse(bitTree P)
    119 {
    120   bitTree T;
    121   T=P->lchild;
    122   while(T!=P)                                     //判断是否空树
    123     {
    124       while(T->ltag==Link)                         //从左孩子开始,直到叶子结点
    125         {
    126           T=T->lchild;
    127         }
    128       visit(T);
    129       while(T->rtag==Thread && T->rchild!=P) //根据线索,访问后继结点。并且后继结点不是指向头结点的
    130         {
    131           T=T->rchild;
    132           visit(T);
    133         }
    134       T=T->rchild;
    135     }
    136 }
    137 
    138 
    139 int main()
    140 {
    141   bitTree P,T;
    142   int level =1;                     //表示该结点的深度
    143   char *arr="ab d  ce   ";             //构造二叉树所需结点(按前序遍历方式输入)
    144   create_tree(&T,&arr);             //构造二叉树
    145   printf("pre_order_traverse:先序遍历:
    ");
    146   pre_order_traverse(T,level);         //前序遍历输出二叉树
    147   printf("in_order_traverse:中序遍历:
    ");
    148   in_thread(&P,T);                     //二叉树线索化
    149   in_order_traverse(P);             //输出线索化后的二叉树
    150   return 0;
    151 }
  • 相关阅读:
    yii 引入文件
    CodeForces 621C Wet Shark and Flowers
    面试题题解
    POJ 2251 Dungeon Master
    HDU 5935 Car(模拟)
    HDU 5938 Four Operations(暴力枚举)
    CodeForces 722C Destroying Array(并查集)
    HDU 5547 Sudoku(dfs)
    HDU 5583 Kingdom of Black and White(模拟)
    HDU 5512 Pagodas(等差数列)
  • 原文地址:https://www.cnblogs.com/wangmengmeng/p/4846610.html
Copyright © 2020-2023  润新知