线索二叉树

来源:互联网 发布:配置ftp网络yum源 编辑:程序博客网 时间:2024/04/20 08:25

       二叉树作为存储结构只能保存其左右孩子结点信息,不能获取结点的前驱和后继信息。同时二叉树结构存在很多个空指针域。一个n个结点的二叉树会形成n+1个空指针域。可以利用这些空指针完成结点前驱和后继信息的补充。具体方法如下:将结点中lchild为空的指针指向其前驱结点;将结点中rchild为空的指针指向其后继结点。指向前驱和后继的指针称为线索。加上线索的二叉树结构称为线索二叉树。

    

     程序说明:使用Qt完成,输入输出使用的Qt类

                         前序顺序构建二叉树。用中序遍历添加线索

                         可以完成二叉树的正向遍历和反向遍历

                         添加头节点使得整个二叉树形成一个环状


头文件:

typedef enum{Link,Thread} TagType;struct BiThrNode{ char data; BiThrNode *lchild,*rchild; TagType lTag,rTag;};class BiThrTree{public:    explicit BiThrTree();    ~BiThrTree();    BiThrNode *createBiTree();    void deleteBiThrTree(BiThrNode *node);    BiThrNode *getRoot();    void Thr_InOrder_Forward(BiThrNode *header);//线索二叉树中序正向遍历    void Thr_InOrder_Reverse(BiThrNode *header);//线索二叉树中序反向遍历private:    void inThreading(BiThrNode *currentNode);//中序线索化二叉树    BiThrNode *inThreading_addHeader(BiThrNode *root);//为线索二叉树添加头结点以形成一个闭合的环    BiThrNode *m_root=nullptr;    BiThrNode *pre=nullptr  ;//记录刚刚访问过的结点};


cpp:

#include "bithrtree.h"#include <QDebug>#include <QTextStream>BiThrTree::BiThrTree(){    m_root=createBiTree();    m_root=inThreading_addHeader(m_root);}BiThrTree::~BiThrTree(){    deleteBiThrTree(m_root);}//构造二叉树BiThrNode *BiThrTree::createBiTree(){    char ch;    QTextStream in(stdin);    in>>ch;    BiThrNode *node;    if(ch=='#')        node=nullptr;    else    {        node=new BiThrNode;        node->data=ch;        node->rTag=Link;        node->lTag=Link;        qDebug()<<"输入左节点:";        node->lchild=createBiTree();        qDebug()<<"输入右节点:";        node->rchild=createBiTree();    }    return node;}void BiThrTree::deleteBiThrTree(BiThrNode *node){    if(!node)        return;    deleteBiThrTree(node->lchild);    deleteBiThrTree(node->rchild);    delete node;    node=nullptr;}BiThrNode *BiThrTree::getRoot(){    return m_root;}//中序遍历线索化二叉树void BiThrTree::inThreading(BiThrNode *currentNode){    if(!currentNode)        return;    inThreading(currentNode->lchild);    if(!currentNode->lchild)    {        currentNode->lTag=Thread;        currentNode->lchild=pre;    }    if(!pre->rchild)    {        pre->rTag=Thread;        pre->rchild=currentNode;    }    pre=currentNode;    inThreading(currentNode->rchild);}BiThrNode *BiThrTree::inThreading_addHeader(BiThrNode *root){    //[1] 实例化并添加一个头结点    BiThrNode *header=new  BiThrNode;    header->lTag=Link;    header->rTag=Thread;    header->rchild=header;    //[1]    if(!root)        header->lchild=header;    else    {        header->lchild=root;        pre=header;        inThreading(root);        header->rchild=pre;//头结点的右指针指向中序变量的最后一个结点        //线索二叉树中的最后一个结点的rchild指向头结点        pre->rTag=Thread;        pre->rchild=header;    }    return  header;}//线索二叉树中序正向遍历(从头向尾遍历)void BiThrTree::Thr_InOrder_Forward(BiThrNode *header){    BiThrNode *p;//指向当前位置的指针    p=header->lchild;    while(p!=header)    {        while(p->lTag==Link)//找到线索二叉树中序遍历的第一个结点            p=p->lchild;        qDebug()<<p->data;        while(p->rTag==Thread&&p->rchild!=header)        {            //表明此时rchild指针没有指向一棵子树 二是存放的是后继节点            p=p->rchild;            qDebug()<<p->data;        }        p=p->rchild;    }}//线索二叉树中序反向遍历(从尾向头遍历)void BiThrTree::Thr_InOrder_Reverse(BiThrNode *header){    BiThrNode *rp;//指向当前位置的指针    rp=header->rchild;    while(rp!=header)    {        while(rp->rTag==Link)        {           rp=rp->rchild;//妈蛋 竟然没有给rp重新赋值        }        qDebug()<<rp->data;        while (rp->lTag==Thread&&rp->lchild!=header)        {            rp=rp->lchild;            qDebug()<<rp->data;        }        rp=rp->lchild;    }}

main函数:

#include <QCoreApplication>#include <QDebug>#include <QObject>#include "bithrtree.h"int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);     qDebug()<<"Input character:";     BiThrTree biThrTree;     qDebug()<<"Thr_InOrder_Forward:";     biThrTree.Thr_InOrder_Forward(biThrTree.getRoot());     qDebug()<<"Thr_InOrder_Reverse:";     biThrTree.Thr_InOrder_Reverse(biThrTree.getRoot());    return a.exec();}


结果:



1 0
原创粉丝点击