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

    可学习的博客:

    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 }
  • 相关阅读:
    第三次个人作业
    第二次结对作业
    第一次结对作业
    第二次编程作业
    第一次编程
    第一次博客作业
    个人总结
    第二次结对作业
    软件工程-个人总结
    第三次个人作业
  • 原文地址:https://www.cnblogs.com/wangmengmeng/p/4846610.html
Copyright © 2011-2022 走看看