数据结构--树和二叉树--二叉树的线索化

本文详细阐述了二叉树的线索化过程及其遍历操作,通过增加结点标志域,实现非线性结构到线性序列的转换,以便于遍历和查找。重点介绍了线索化的具体步骤和中序遍历的实现方法。

    遍历二叉树的过程实际上是以一定的规则将二叉树中的结点排成一个线性序列,是将非线性结构进行线性化操作,使得每一个结点(除了第一个结点和最后一个)在这写线性序列中有且仅有一个前驱和后继。我们已经由二叉树的性质知道:在有n个结点的二叉链表中必定含有n+1个空链域。其思想就是利用这写空链域来存储前驱和后继信息。试作如下规定:若结点有左子树,则其lchild指向其左孩子,否则令lchild指向其前驱;若结点有右子树,则其rchild指向其右子树,否则令rchild指向其后继。为此,在树的结点中增加两个标志域:LTag,RTag; LTag=0 lichild指向其左子树,LTag=1 lichild指向其前驱,RTag=0 lichild指向其右子树,LTag=1 lichild指向其后继。

其线索化和线索化后的遍历操作如下:

//二叉树的线索存储表示和线索化

enum PointerTag {Link,Thread}; //Link==0:指针,Thread=1:线索

typedef struct BiThrNode{
    TElemType data;
    struct BiThrNode *lchild,*rchild;  //左右孩子指针
    PointerTag LTag,RTag;  //左右标志
    BiThrNode(){
        data=0;
        lchild=NULL;
        rchild=NULL;
        LTag=Link;
        RTag=Link;
    }
}BiThrNode,*BiThrTree;

//按照先序创建以二叉线索为存储结构的二叉树
Status CreateBiThrTree(BiThrTree &T){
    TElemType ch;
    cin>>ch;
    if(ch=='@') T=NULL;
    else{
        if(!(T=(BiThrNode*)malloc(sizeof(BiThrNode)))) return ERROR;
        T->data=ch;
        T->LTag=Link;
        T->RTag=Link;
        CreateBiThrTree(T->lchild);
        CreateBiThrTree(T->rchild);
    }
    return OK;
}

BiThrNode *pre=NULL;
void InThreading(BiThrTree p){
    if(p){
        InThreading(p->lchild);  //左子树线索化
        if(!p->lchild){
            p->LTag=Thread;
            p->lchild=pre;
        }
        if(!pre->rchild){
            pre->RTag=Thread;
            pre->rchild=p;
        }
        pre=p;
        InThreading(p->rchild);
    }
}

//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
Status InOrderThreading(BiThrTree &Thrt,BiThrTree T){
    if(!(Thrt=(BiThrNode*)malloc(sizeof(BiThrNode)))) exit(OVERFLOW);
    Thrt->LTag=Link; Thrt->RTag=Thread;  //建立头结点
    Thrt->rchild=Thrt;   //右指针回指
    if(!T) Thrt->lchild=Thrt; //如果树为空,左指针回指
    else{
        Thrt->lchild=T;
        pre=Thrt;
        InThreading(T);
        pre->rchild=Thrt;
        pre->RTag=Thread;  //最后一个结点线索化
        Thrt->rchild=pre;
    }
    return OK;
}

//对以双向链表为存储结构的二叉树进行遍历
Status InOrderTraverse_Thr(BiThrTree T,Status (*Visit)(TElemType e)){
    BiThrNode *p=NULL;
    p=T->lchild;  //p指向根结点
    while(p!=T){ //空树或者遍历结束
        while(p->LTag==Link) p=p->lchild;
        if(!Visit(p->data)) return ERROR;
        while(p->RTag==Thread&&p->rchild!=T){
            p=p->rchild;
            Visit(p->data);
        }
        p=p->rchild;
    }
    return OK;
}

Status PrintData(TElemType e){
    cout<<e<<" ";
    return OK;
}

int main()
{
    BiThrTree thrt,t;
    CreateBiThrTree(t);
    InOrderThreading(thrt,t);
    InOrderTraverse_Thr(thrt,PrintData);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值