大话数据结构--二叉树建立及结构实现

155 阅读2分钟

「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」。

前言

废话不多,数据结构必须学! 每天更新一章,一篇写不完的话会分成两篇来写~

资料获取

image.png

6.8二叉树的建立

在内存中建立好一颗二叉树我们才能进行遍历

所以,如果我们要在内存中建立一个二叉树

我们建立一个扩展二叉树,什么是扩展二叉树,就是在给普通二叉树的每个结点的空指针引出一个虚结点,并给它赋值(#)

如图所示:

image-20211116140825710

代码实现:

 /*按前序输入二叉树中结点的值(一个字符)*/
 /* #表示空树,构造二叉链表表示二叉树T。*/
 void CreateBiTree (BiTree *T )
 {
     TElemType ch;
     scanf ( "%c",&ch) ;
     if (ch=='#')
         *T=NULL;
     else
     {
         *T= (BiTree) malloc (sizeof(BiTNode)) ;
         if(!*T)
             exit (OVERFLOW) ;
         (*T)->data=ch; /*生成根结点
         CreateBiTree (&(*T)->1child);  /*构造左子树*/
         CreateBiTree (&(*T)->rchild) ; /*构造右子树*/
     }
 }
 ​

6.9线索二叉树

6.9.1线索二叉树原理

为了解决空指针占用内存的问题,把这些空指针的位置利用起来,指向前驱和后继的,它们称为线索,加上线索的二叉链表称为线索链表,相应的二叉树就称为线索二叉树

我们对二叉树以某种线索遍历使其变为线索二叉树的过程称作是线索化

为了更好的区分,我们这样定义结点的结构

image-20211116142059925

其中:

ltag为0时指向该结点的左孩子,为1时指向该结点的前驱。 rtag为0时指向该结点的右孩子,为1时指向该结点的后继。

如下:

image-20211116142128399

6.9.2线索二叉树结构实现

 /*二叉树的二叉线索存储结构定义*/
 typedef enum {Link, Thread} PointerTag; /* Link=-0 表示指向左右孩子指针*/
                                         /* Thread==1 表示指向前驱或后继的线索*/
 ​
 typedef struct BiThrNode        /*二叉线索存储结点结构*/
 { 
     TElemType data;     /*结点数据*/
     struct BiThrNode *lchild, *rchild;  /*左右孩子指针*/
     PointerTag LTag;
     PointerTag RTag;        /*左右标志*/
 } BiThrNode, *BiThrTree;

线索化的实质就是将二叉链表中的空指针改为指向前驱或后继的线索。由于前驱和后继的信息只有在遍历该二叉树时才能得到,所以线索化的过程就是在遍历的过程中修改空指针的位置

如果所用的二叉树需经常遍历或查找结点时需要某种遍历序列中的前驱和后继,那么采用线索二叉链表的存储结构就是非常不错的选择。