数据结构_树_二叉树的线索化_C++实现

本文介绍了一种使用C++实现的二叉树线索化技术,包括如何通过先序遍历来建立二叉树,以及如何进行中序线索化遍历。通过交互式输入构建二叉树,并提供了一个主函数来选择不同的操作,如创建二叉树、线索化遍历等。

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

"head.h"


#include<iostream>
#define LINK 0//定义节点类型:指针
#define THREAD 1//定于节点类型:线索
using namespace std;
///////////////////////二叉树树节点类
class BitNode
{
public:
    BitNode();
    char ch;
    BitNode *lchild,*rchild;
    int LTag,RTag;
};
///////////////////////二叉树节点类的构造函数
BitNode::BitNode()
{
    lchild=rchild=NULL;
    LTag=RTag=LINK;
}
///////////////////////////////BiTree_Thread类
class BiTree_Thread
{
public:
    BiTree_Thread();
    void PreOrderCreatBiTree();
    void InOrderTraverse_Thread();
private:
    void ReMove();
    void InOrderThreading();
    void InThreading(BitNode *&);
    void Creat(BitNode *&);
    void ReMoveBiTree(BitNode *&);
    BitNode *root,*pre,*p,*start;
    char ch;
};
///////////////////////////////BiTree_Thread类的构造函数
BiTree_Thread::BiTree_Thread()
{
    root=pre=p=start=NULL;
}
/////////////////////////////////////////先序建立二叉树接口函数
void BiTree_Thread::PreOrderCreatBiTree()
{
    cout<<"PreOrderCreatBiTree Called !"<<endl<<endl;
    cout<<"Please Input The BiTree In PreOrder :"<<endl<<endl;
    ReMove();//移除原先的树
    Creat(root);//建立新树
    cin.clear();//解除cin的异常状态
}
//////////////////////////////////////先序递归建立二叉树
void BiTree_Thread::Creat(BitNode *&t)
{
    if(cin>>ch)
    {
        if(ch!='#')
        {
            t=new BitNode;//开辟新节点
			t->ch=ch;
            Creat(t->lchild);//递归建立其左子树
            Creat(t->rchild);//递归建立其右子树
        }
        else
            t=NULL;
    }
}
/////////////////////////////////////////////////中序线索化遍历二叉树接口函数
void BiTree_Thread::InOrderTraverse_Thread()
{
    cout<<"InOrderTraverse_Thread Called !"<<endl<<endl;
    if(root==NULL)//若树空
    {
        cout<<"BiTree Is Empty !"<<endl<<endl;
        PreOrderCreatBiTree();//新建一棵二叉树
    }
	if(start==NULL)//若未被线索化
		InOrderThreading();//中序线索化
    p=start->lchild;//p转到root节点
    while(p!=start)//循环遍历之
    {
        while(p->LTag==LINK)//如果指向左孩子的是指针
        {
            p=p->lchild;//转到其左孩子
        }
        cout<<p->ch<<endl;//访问节点
		while(p->RTag==THREAD&&p->rchild!=start)//当指向右孩子的是线索时
        {
            p=p->rchild;//转向右孩子
            cout<<p->ch<<endl;//访问之
        }
        p=p->rchild;//转向右孩子
    }
}
//////////////////////////////////////中序线索化主程序
void BiTree_Thread::InOrderThreading()
{
    start=new BitNode;//开辟一个额外的节点作为线索化遍历的起点和终点
    start->LTag=LINK;//左标志设为指针
    start->RTag=THREAD;//右标志初始化为线索
    start->rchild=start;//起点的右孩子回指向其自身
    if(root==NULL)//若不存在一颗二叉树
    {
        start->lchild=start;//左指针回指
    }
    else//否则
    {
        start->lchild=root;//起始点指向二叉树的根节点
        pre=start;//初始化pre指向起始点
        InThreading(root);//从根节点开始线索化
        pre->RTag=THREAD;//处理线索化的最后一个节点
        pre->rchild=start;
        start->rchild=pre;
    }
}
//////////////////////////////////////////中序线索化递归部分
void BiTree_Thread::InThreading(BitNode *&p)
{
    if(p)//若节点存在
    {
        InThreading(p->lchild);//线索化其左子树
        if(p->lchild==NULL)//处理p指向的节点的前驱
        {
            p->LTag=THREAD;
            p->lchild=pre;
        }
        if(pre->rchild==NULL)//处理pre指向的节点的后继
        {
            pre->RTag=THREAD;
            pre->rchild=p;
        }
		pre=p;//pre紧跟p
        InThreading(p->rchild);//线索化其右子树
    }
}
/////////////////////////////////////////移除二叉树主调函数
void BiTree_Thread::ReMove()
{
    if(root!=NULL)//如果树不空
    {
        ReMoveBiTree(root);//移除整棵树
        if(start!=NULL)//如果已经被线索化
        {
            delete start;//删除start节点
			start=NULL;//置start为NULL
        }
		root=NULL;//置root为NULL
    }
}
////////////////////////////////////////////移除二叉树被调函数
void BiTree_Thread::ReMoveBiTree(BitNode *&t)
{
	if(t!=NULL)//此条件用于未线索化的二叉树
	{
		if(t->LTag!=THREAD)//此条件用于线索化的二叉树
			ReMoveBiTree(t->lchild);//递归移除其左子树
		if(t->RTag!=THREAD)//此条件用于线索化的二叉树
			ReMoveBiTree(t->rchild);//递归移除其右子树
		delete t;//删除节点
	}
}



"main.cpp"



#include<iostream>
#include"head.h"
using namespace std;

int main()
{
    BiTree_Thread t;
    char choice;
    while(1)
    {
        cout<<"Your Choice , Please ?"<<endl<<endl
        <<"1 . PreOrderCreatBiTree"<<endl
        <<"2 . InOrderTraverse_Thread"<<endl
        <<"9 . Quit"<<endl<<endl;
        cin>>choice;
        switch(choice)
        {
            case '1':
                 t.PreOrderCreatBiTree();
                 break;
            case '2':
                 t.InOrderTraverse_Thread();
                 break;
            case '9':
                 return 0;
                 break;
            default:
                    cout<<"No Such Choice !"<<endl<<endl;
                    break;
        }
    }
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值