二叉树 —— 线索二叉树

二叉树

定义:
  • 每个结点的度不能大于2;

  • 每个节点的孩子结点次序不能任意颠倒

性质:
  • 在二叉树的第i层上至多有2i-1个结点;

  • 深度为K的二叉树至多有2i-1个结点;

  • 任意一棵二叉树T,若终端结点数为n0,而其度数为2的结点数为n2,则 n0 = n2+1

  • 具有n个结点的完全二叉树的深度 long2n(向下取整) +1

存储结构(链表)
 //二叉链表结点结构;
 typedef struct Node{
     DataType data;
     struct Node *LChild;
     struct Node *RChild;
 }BiTNode,*BiTree;

1.建立二叉链表方式存储的二叉树(扩展二叉树**空结点用"."来表示**

  • 参数采用二级指针(才可在自定义函数内返回创建的结点,创建出树)

 //扩展先序遍历序列创建二叉链表;
 void CreateBiTree(BiTree *bt){                              //参数为二级指针(*bt);
     char ch;
     ch=getchar();                                           //一次性输入,逐个输入(回车也当为一个字符); 
     if(ch == '.' ){
         *bt=NULL;
     }
     else {
         *bt = (BiTree) malloc (sizeof (BiTNode));           //动态开辟二叉结点; 
         (*bt)->data = ch;
         CreateBiTree(&(*bt)->Lchild);                       //递归调用左子树; 
         CreateBiTree(&(*bt)->Rchild);                       //递归调用右子树; 
     }   
 } 

线索二叉树

定义
  • 二叉树的遍历运算是将二叉树中结点按一定规律线性化的过程。

  • 有n个结点的二叉链表中共有2n个链域,但有n+1个空指针域,利用这n+1个空指针域建立线索(相应的前后继结点)。

 //线索二叉树的结点结构;
 typedef struct Node {
     ThreadType data;
     struct Node *LChild,*RCild;
     int Ltag,Rtag;                      //标志位,标志位=0表示存在左或右孩子,否则建立相应的前驱或后继结点;
 }BiTNode,*BiTree;
  • 算法步骤:

    • 建立一个二叉树(创建的同时给标志位Ltag、Rtag赋初值);

    • 中序遍历二叉树的同时建立中序线索树;

      1.设置两个指针(p,pre)分别存放当前结点和此结点的前驱结点;

      2.中序遍历的时建立相应结点的前驱结点和后继结点;

 //建立中序线索树;
 void Inthread(BiTree p){
     //建立在中序遍历二叉树的基础之上;
     static BiTree pre = NULL;                       //设置静态变量pre;
     if (p == NULL){
         return;
     }
     Inthread (p->LChild);                           //遍历左子树;
     if(p->LChild == NULL ){                         //建立p的前驱线索;
             p->Ltag = 1;
             p->LChild = pre;
     }
     if ( pre!= NULL&&pre->RChild==NULL ){           //置后继线索,pre!=NULL,开始时判断以防止程序错误;
             pre->Rtag = 1;
             pre->RChild = p;
     }
             pre = p;                                //当前访问结点为下一个访问结点的前驱;
     Inthread(p->RChild);
 }
 //在中序线索树中找结点的后继;
 BiTree InNext (BiTree p){
     static BiTree q = NULL;
     if (p->Rtag==1) {                               //标志位为1,可直接找到后继结点;
         q = p->RChild;
     }
     else {                                          //右标志为0,则要找到右子树最左下角的结点;
         q = p->RChild;                              
         while (q->Ltag==0){                         //查找最左下角的结点;
             q = q->LChild;
         }
     }  
     return q;
 }
 //在中序线索树中找结点的前驱;
 BiTree INpre (BiTree p){
     static BiTree q = NULL;
     if (p->Ltag == 1){                              //标志位为1,可直接找到前驱结点;
         q = p->LChild;
     }
     else {                                          //坐标志位0,则要找到左子树最右下角的结点;
         q = p->LChild;
         while (q->Ltag == 0){                       //查找最左下角的结点;
             q = q->RChild;                  
         }
     }
     return q;
 }
 //中序遍历线索二叉树;
 void ThreadOrder(BiTree bt){
     BiTNode *p;
     if (bt == NULL) return;
     p = bt;
     while (p->Ltag == 0){                           //查找中序遍历的第一个结点p;
         p = p->LChild;
     }
     printf("%d",p->data);                           //访问第一个结点;
     while (p->RChild !=NULL){                       //当p存在后继,依次访问后继节点;
         p = InNext(p);
         printf("%d",p->data);
     }
 }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值