线索二叉树

(一)线索二叉树原理

线索二叉树:加上线索的二叉树

线索:结点的前驱和后继指针

空链域和非空链域:不管二叉树的形态如何,二叉树中空链域的个数总是大于非空链域的个数。有n个结点的二叉树,一共有2n个链域,n-1个非空链域,n+1个空链域。所以考虑用二叉树的空链域来存放指向结点的前驱和后继的指针。

建立线索的规则:若结点有左子树,则其lchild域指向其左孩子,否则指向其前驱;若结点有右子树,则其rchild域指向其右孩子,否则指向其后继。

显然,需要标志来判断,lchild和rchild是指向左右孩子还是指向前驱和后继,因此在每个结点增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量

结点结构:
这里写图片描述

其中:(1)ltag为0时指向该结点的左孩子,为1时指向该结点的前驱;(2)rtag为0时指向该结点的右孩子,为1时指向该结点的后继;

这里写图片描述

(二)线索二叉树结构实现
2.1 二叉树的二叉线索存储结构

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

}BiThrNode,*BiThrTree;

2.2 创建一个二叉树,按照前序遍历方式输入

void CreateBiThrTree(BiThrTree *T)  
{  
   char c;
   scanf_s("%c",&c);
   if('#'==c)
   {
       T=NULL;
   }
   else
   {
      *T=(BiThrNode*)malloc(sizeof(BiThrNode));
     (*T)->data=c;
     (*T)->LTag=Link;
     (*T)->RTag=Link;
     CreateBiThrTree(&(*T)->lchild);
     CreateBiThrTree(&(*T)->rchild);
   }
}  

2.3 中序遍历线索化

void InThreading(BiThrTree T)  
{  
    if (T)  
    {  
        InThreading(T->lchild);      //递归左孩子线索化  

        //结点处理  
        if (!T->lchild)      //如果该结点没有左孩子,设置ltag为Thread,并把lchild指向刚刚访问的结点。  
        {  
            T->ltag = Thread;  
            T->lchild = pre;  
        }  

        if (!pre->rchild)  
        {  
            pre->rtag = Thread;  
            pre->rchild = T;  
        }  

        pre = T;  

        InThreading(T->rchild);      //递归右孩子线索化  
    }  
}  
void InOrderThreading(BiThrTree *p,BiThrTree T)  
{  
    *p = (BiThrTree)malloc(sizeof(BiThrNode));  
    (*p)->ltag = Link;  
    (*p)->rtag = Thread;  
    (*p)->rchild = *p;  
    if (!T)  
    {  
        (*p)->lchild = *p;  
    }  
    else  
    {  
        (*p)->lchild = T;  
        pre = *p;  

        InThreading(T);  
        pre->rchild = *p;  
        pre->rtag = Thread;  
        (*p)->rchild = pre;  
    }  
}  

void visit(char c)  
{  
    printf_s("%c", c);  
}  

//中序遍历二叉树,非递归  
void InOrderTraverse(BiThrTree T)  
{  
    BiThrTree p;  
    p = T->lchild;  
    while (p != T)  
    {  
        while (p->ltag == Link)  
        {  
            p = p->lchild;  
        }  
        visit(p->data);  

        while (p->rtag == Thread && p->rchild != T)  
        {  
            p = p->rchild;  
            visit(p->data);  
        }  
        p = p->rchild;  
    }  
}  

int main()  
{  
    BiThrTree P, T = NULL;  
    CreateBiThrTree(&T);  

    InOrderThreading(&P, T);  

    printf_s("中序遍历输出结果为:");  
    InOrderTraverse(P);  
    printf_s("\n");  
    system("pause");  
    return 0;  
}</span>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值