中序线索化二叉树

本文介绍了一种二叉树的线索化方法及其在中序遍历中的应用。通过递归创建二叉树并对其进行线索化处理,使得每个节点能够直接指向其前驱和后继节点,从而优化了遍历过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



先理解图,在看代码。

#include <iostream>
using namespace std;
typedef struct node
{
    char data;
    struct node *rchild;
    struct node *lchild;
    int rtag;   // rtag=0时,表示Rchild指向该结点的右孩子;为1时,表示rchild指向该结点的线性后继结点;
    int ltag;    //Ltag=0时,表示lchild指向该结点的左孩子,为1时,表示Lchild指向该结点的线性前驱结点;
}BiTNode,*BiTree;
void creat(BiTree &T) //递归创建二叉树
{
    char ch;
    scanf("%c",&ch);
    if(ch=='#')
    {
        T=NULL;
    }
    else
    {
        T=(BiTNode*)malloc(sizeof(BiTNode));
        T->data=ch;
        creat(T->lchild);
        creat(T->rchild);
    }
}
void InOrderTraverse(BiTree T)  //递归中序遍历
{
    if(T==NULL)
    {
        return;
    }
    InOrderTraverse(T->lchild);
    printf("%c ",T->data);
    InOrderTraverse(T->rchild);
}
BiTree Pre;   //全局变量,前驱结点
void InThreading(BiTree &p)   //线索化
{
    if(p)
    {
        InThreading(p->lchild);  //线索化左子树
        if(!p->lchild)
        {
            p->ltag=1;
            p->lchild=Pre; //线索化左孩子,指向前驱
        }
        if(!Pre->rchild)
        {
            Pre->rtag=1;
            Pre->rchild=p;  //线索化右孩子,指向后继
        }
        Pre=p;            //更新前驱结点
        InThreading(p->rchild);   //线索化右子树

    }
    }
void InOrderThreading(BiTree &Thrt,BiTree &T)  //线索化二叉树,并处理根结点,及最后一个访问结点
{
    Thrt->rchild=Thrt;  //先指向本身
    Thrt->ltag=0;
    if(!T)
    {
        Thrt->lchild=Thrt;  //指向自己
        return;
    }
    
    Pre=Thrt;
    Thrt->lchild=T;
    InThreading(T);
    
    //处理Thre与最后一个访问结点。
    Pre->rchild=Thrt;
    Pre->rtag=1;
    Thrt->rchild=Pre;
    Thrt->rtag=1;
}
int vis(BiTree t)
{
    cout<<t->data<<" ";
    return 1;
}
int inorder_traverse_thread(BiTree Thrt, int (*visit)(BiTree t))   //线索化后的二叉树中序遍历
{
    BiTree	p;
    p = Thrt->lchild;
    while (p != Thrt)
    {
        while (p->ltag ==0)  //找到第一个线索化的左子树
        {
            p = p->lchild;
        }
        visit(p);
        while (p->rtag == 1 && p->rchild != Thrt)   //如果该结点的右孩子是线索,则沿线索找到后继结点
        {
            p = p->rchild;
            visit(p);
        }
        p = p->rchild;  //进入右子树访问
    }
    return 1;
}
int main()
{
    BiTree T;
    creat(T);
    InOrderTraverse(T);
    cout<<endl;
    
    BiTree Thrt;   
    Thrt=(BiTNode*)malloc(sizeof(BiTNode));
    InOrderThreading(Thrt, T);
    inorder_traverse_thread(Thrt, vis);
    cout<<endl;
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值