数据结构 线索二叉树

线索二叉树

将指向空的指针加以利用,空左子树指针指向该节点直接前驱,空右子树指针指向该节点直接后继,通过线索可以加快遍历速度

结构定义

enum PointerTag { Link = 0, Thread = 1 };

template <typename ElemType>
struct BiThrNode
{
	ElemType data;
	BiThrNode* lchild, * rchild;
	PointerTag LTag, RTag;
};

template<typename ElemType>
using BiThrTree = BiThrNode<ElemType>*;

基本操作
遍历:通过线索进行中序遍历,空右子树指针直接指向直接后继,通过指针可以快速找到下一个节点

template<typename ElemType>
Status inOrderTraverse_thr(BiThrTree<ElemType>& T, Status(*visit)(BiThrTree<ElemType>&))//中序遍历线索二叉树
{
	BiThrNode<ElemType>* head = T;//头节点
	T = T->lchild;//树根
	while (T != head)//当前节点不是头节点
	{
		while (T->LTag == Link)//找到中序遍历第一个节点,即最左边的节点
			T = T->lchild;
		visit(T);//访问该节点
		while (T->RTag == Thread && T->rchild != head)//该节点无右子树,直接通过右儿子找到直接后继节点并访问
		{
			T = T->rchild;
			visit(T);
		}
		T = T->rchild;//该节点有右子树,因为是中序,访问到该节点就表明已经访问过该节点的左子树了,所以开始访问该节点的右子树
	}
	return OK;
}

创建线索二叉树:首先创建一个头节点,头节点的左子树指针指向要创建的二叉树的根节点,然后通过递归创建二叉树

template<typename ElemType>
Status creatBiThrTree(BiThrTree<ElemType>& T, ElemType*& data)//创建线索二叉树
{
	T = new BiThrNode<ElemType>;
	T->lchild = NULL;
	T->rchild = NULL;
	_creatBiThrTree(T->lchild, data);
	return OK;
}

template<typename ElemType>
Status _creatBiThrTree(BiThrTree<ElemType>& T, ElemType*& data)//创建线索二叉树
{
	ElemType et;
	char flag = '$';
	et = *data;
	if (et == flag)
		T = NULL;
	else
	{
		T = new BiThrNode<ElemType>;
		T->data = et;
		_creatBiThrTree(T->lchild, ++data);
		_creatBiThrTree(T->rchild, ++data);
	}
	return OK;
}

中序线索化:首先修改头节点各个变量的值,然后开始中序线索化头节点的右子树,即二叉树;中序线索化二叉树通过递归实现,先中序线索化左子树,然后线索化根节点,最后中序线索化右子树

template<typename ElemType>
Status inOrederThreading(BiThrTree<ElemType> T)//中序线索化二叉树
{
	BiThrNode<ElemType>* head = T;//先修改好头节点的各个数据
	head->LTag = Link;
	head->RTag = Thread;
	if (!head->lchild)//如果没有左子树,即表示为空树
	{
		head->lchild = head;
		head->rchild = head;
		return ERROR;
	}
	_inOrderThreading(T->lchild, T);//中序线索化
	T->RTag = Thread;//修改最后一个节点的各个数据
	T->rchild = head;
	head->rchild = T;//将头节点的右儿子指向最后一个节点
	return OK;
}

template<typename ElemType>
Status _inOrderThreading(BiThrTree<ElemType>& T, BiThrNode<ElemType>*& pre)//中序线索化二叉树
{//先中序线索化左子树,在根节点,最后右子树
	if (T)
	{
		_inOrderThreading(T->lchild, pre);//中序线索化左子树
		if (T->lchild)//判断是否有左子树,修改LTag的值
			T->LTag = Link;
		else
		{
			T->LTag = Thread;
			T->lchild = pre;
		}
		if (pre->rchild)//判断前驱是否有右子树
			pre->RTag = Link;
		else
		{
			pre->RTag = Thread;
			pre->rchild = T;
		}
		pre = T;//当前节点改为前驱节点
		_inOrderThreading(T->rchild, pre);//中序线索化右子树
	}
	return OK;
}

测试

void testBiThrTree()//测试线索二叉树
{
	BiThrTree<char> T;
	char* data = (char*)"-*a$$b$$c$$";
	cout << "创建线索二叉树" << endl;
	creatBiThrTree(T, data);
	inOrederThreading(T);
	cout << "中序遍历:";
	inOrderTraverse_thr(T,print_thr);
	cout << endl;

	cout << endl;
	system("pause");
}

结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值