C++实现的线索二叉树

本文介绍了C++如何实现线索二叉树,重点在于结构体中ltag和rtag标志位的使用,用于存储前驱和后继节点指针。通过前序输入,程序能输出中序遍历结果,虽然效果略显粗糙,但基本功能得以实现。
摘要由CSDN通过智能技术生成

线索二叉树的概念就不赘述了,最核心的定义就是:结构体中左右标志位的选取,本文中以ltag表示左节点,当ltag为false时,放置左孩子,true时放置前驱节点指针,同理,以rtag表示右节点,当rtag为false时,放置右孩子,true时放置后继节点指针。

以下代码中有详细注释~👧(不过线索二叉树真的好难懂鸭)

typedef struct  BiTreeNode
{
	char data;
	BiTreeNode *lchild;
	BiTreeNode *rchild;
	bool ltag = false;//指定0为孩子 1为前驱后继
	bool rtag = false;//首先指定为0

}*BiClueTree;//起别名 等价于BiClueTree p1=BiTreeNode *p2
BiClueTree Previous;
void CreateBiClueTree(BiClueTree *t)
{
	//相当于传地址的操作,可以改变t
	//(*t)是一个BiTreeNode型指针
	char c;
	scanf_s("%c", &c, 1);
	if ('#'==c)
	{
		*t = NULL;
		return;
	}
	(*t) = new BiTreeNode();
	(*t)->data = c;
	CreateBiClueTree(&((*t)->lchild));
	//(*t)->lchild是一个BiTreeNode型指针,也就相当于BiClueTree变量,那么需要进行取地址操作才能进行递归
	CreateBiClueTree(&((*t)->rchild));

}
void Clueing(BiClueTree t)
{
	if (t)//树不为空
	{
		Clueing(t->lchild);//一直递归左子树 直到这个t节点属于叶子节点
		if (!t->lchild)
		{
			t->lchild = Previous;//最第一次进来的时候 也就是最左子树的叶子节点 指向头节点的左边
			t->ltag = true;
		}
		if (!Previous->rchild)
		{
			Previous->rchild = t;
			Previous->ltag = true;
		}
		Previous = t;
		Clueing(t->rchild);//这块还没怎们搞懂为啥要递归右孩子
	}
}
void ClueTheTree(BiClueTree *head, BiClueTree t)
{
	(*head) = new BiTreeNode();
	(*head)->rchild = (*head);
	(*head)->rtag = false;//刚开始创建的时候右孩子指向自己
	if (t==NULL)
	{
		(*head)->lchild = (*head);
		(*head)->ltag = false;//树为空时左孩子还是指向自己
	}
	else
	{
		Previous = (*head);
		(*head)->lchild = t;
		(*head)->ltag = false;//此时左孩子是树的节点啦啦啦啦啦~
		Clueing(t);
		Previous->rchild = (*head);//最后一个节点 指回头节点
		Previous->rtag = true;
		(*head)->rchild = Previous;//双向指 和上面一样
	}
}
void ShowTheTree(BiClueTree head)
{
	BiClueTree p;
	p = head->lchild;//指向了根节点
	while (p!= head)//没有走到最左子树的叶子节点时
	{
		while (p->ltag==false)
		{
			p = p->lchild;
		}//结束循环时,找到了那个最左边的根节点
		cout << p->data;
		while (p->rchild != head && p->rtag==false)
		{
			//如果这个节点不是最右子树的节点 并且他有右孩子
			p = p->rchild;
			cout << p->data;
		}
		//如果不满足上述条件
		//那么就是①到了最右子树,现在的p是头节点
		//②p是相对靠右的叶子节点,此时 也应该将p给到他的后继 再让大循环判断其是不是头节点
		//如果是 退出循环 如果不是 因为最右叶子节点没有左孩子,所以输出本身的数据,再进入其【后继】节点
		p = p->rchild;
	}
	cout << endl;
}
void test20()
{
	BiClueTree tree;
	BiClueTree head;
	CreateBiClueTree(&tree);
	ClueTheTree(&head, tree);
	ShowTheTree(head);
}
int main()
{
	cout << "正在测试我的代码。。" << endl;
	srand((unsigned int)time(NULL));
	test20();
	system("pause");
}

以下是效果图🎠
emmm 略显粗糙 。。。第一行是用户输入的前序二叉树,第二行是程序给出的中序遍历结果,emmm,凑合看也还Key拉~✨ 如果明天不懒 就来补图!giao
emmm

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值