数据结构--线索树

本文介绍了如何构建线索二叉树,通过一个字符串表示二叉树元素,并详细阐述了二叉树的中序线索化过程。讨论了如何获取线索树中结点的前驱和后继,以及线索二叉树在需要频繁遍历和查找结点前后继场景下的应用。

线索树的构造思路
(1)首先构造出一棵二叉树
(2)然后将二叉树线索化(1.中序2.先序3.后序)

关于二叉树的建立(方法之一)
(1)用一个字符串来表示二叉树上的元素,其中’#’代表无效结点,然后可以根据自己的需求来调整字符串顺序
char *str = “ABC##DE##F##G#H##”;

希望构建中序遍历是
C B E D F A G H
先序遍历
A B C D E F GH 的二叉树
二叉树建立函数

BinaryNode * CreateTree(char *& str)
{
    BinaryNode* s = NULL;
    if (*str != '#')
    {
        s = (BinaryNode*)malloc(sizeof(BinaryNode));
        s->data = *str;
        s->left = 0;
        s->right = 0;

        s->leftNode = CreateTree(++str);
        s->rightNode = CreateTree(++str);
    }
    return s;
}

二叉树成功建立了以后是线索化
中序线索化

void Make(BiThrNode *p, BiThrNode *&ptr)//对一个结点
{
    if (p != NULL)
    {
        Make(p->leftchild, ptr);
        if (p->leftchild == NULL)
        {//当当前p的前驱书空的时候,因为ptr是他的前驱所以可以赋值
            p->leftchild = ptr;//左是前驱,右是后继
            p->Ltag = THREAD;
        }
        if (ptr != NULL && ptr->righthchild == NULL)
        {//ptr记录的是p的前驱,当前驱的后继是空的时候对前驱进行赋值
            ptr->righthchild = p;
            ptr->Rtag = THREAD;
        }
        ptr = p;
        Make(p->righthchild, ptr);
    }
}

void MakeThread(BiThrNode *p)
{
    if (p == NULL) return;
    BiThrNode *ptr = NULL;
    Make(p, ptr);
    ptr->righthchild = NULL;//后继
    ptr->Rtag = THREAD;
}

获取线索树的第一个结点,以中序的方式

BiThrNode * First(BiThrNode *ptr)
{//查找以ptr为根节点的第一个结点,中序情况
    while (ptr != NULL && ptr->Ltag != THREAD)
    {
        ptr = ptr->leftchild;
    }
    return ptr;
}

获得线索树当前结点的上一个结点

BiThrNode * Last(BiThrNode *ptr)
{//如果是线索那就直接返回,如果不是线索,按照左中右,那就找到左的最后一个
    while (ptr != NULL && ptr->Rtag != THREAD)
    {
        ptr = ptr->righthchild;
    }
    return ptr;
}

获得线索树当前结点的下一个结点

BiThrNode * Next(BiThrNode *ptr)
{
    if (ptr == NULL) return NULL;
    if (ptr->Rtag == THREAD)
    {
        return ptr->righthchild;
    }
    else
    {
        return First(ptr->righthchild);
    }
}

获得当前结点的上一个结点

BiThrNode * Prev(BiThrNode *ptr)
{
    if (ptr == NULL) return NULL;
    if (ptr->Ltag == THREAD)
    {
        return ptr->leftchild;
    }
    else
    {
        return Last(ptr->leftchild);//找ptr的上一个
    }
}

以线索为依据的逆序中序遍历和顺序中序遍历

void ResNiceInOrder(BiThrNode *ptr)
{
    for (BiThrNode *p = Last(ptr); p != NULL; p = Prev(p))
    {
        cout << p->data << " ";
    }
    cout << endl;
}



void NiceInOrder(BiThrNode *ptr)
{
    for (BiThrNode *p = First(ptr); p != NULL; p = Next(p))
    {
        cout << p->data << " ";
    }
    cout << endl;
}

线索二叉树适用范围
若在某程序中所用二叉树需经常遍历或查找结点在遍历所得线性序列中的前驱和后继,则应采用线索链表做存储结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值