线索二叉树

一.原理
利用原来的空链域存放指针,指向树中其他结点,这种指针称为线索
决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag
在这里插入图片描述
线索化的实质就是将二叉链表中的空指针改为指向前驱或后继的线索。由于前驱和后继信息只有在遍历该二叉树时才能得到,所以线索化的过程就是在遍历的过程中修改空指针的过程

二.代码实现

1.创建二叉树
ubmV0L3RyaWdnZXJW,size_16,color_FFFFFF,t_70)
2.中序遍历线索化
处理前驱:针对当前节点,什么时候能得到前驱,访问当前节点的时候就可以,因此要记录上一个节点pre,不过前提是T的左子树为空
处理后继:针对pre节点,什么时候处理后继,访问下一个节点的时候,才能知道当前节点的后继是什么,因此对于下一个节点T来说,pre的后继就是T,因此要对pre进行操作,前提是pre!=NULL且pre的右子树为空
在这里插入图片描述

  1. 遍历线索二叉树
    有了线索二叉树后,对它进行遍历时,其实就等于操作一个双向链表结构
    在这里插入图片描述
    和双向链表结点一样,在二叉树链表上添加一个头结点,令其lchild域的指针指向二叉树的根结点,其rchild域的指针指向中序遍历访问时的最后一个结点。反之,令二叉树的中序序列中第一个结点中,lchild域指针和最后一个结点的rchild域指针均指向头结点 这样的好处是:我们既可以从第一个结点起顺后继进行遍历,也可以从最后一个结点起顺前驱进行遍历。
void InOrderThreading(BiThrTree *p, BiThrTree T)
{
	*p = (BiThrTree)malloc(sizeof(BiThrNode));
	(*p) -> ltag = Link;
	(*p) -> rtag = Thread;
	(*p) -> rchild = *p;
	if(!T)
	{
		(*p) -> lchild = *p;
	}
	else
	{
		(*p) -> lchild = T;
		pre = *p;
		InThreading(T);
		pre -> rchild = *p;
		pre -> rtag = Thread;
		(*p) -> rchild = pre;
	}
}

void visit(char c)
{
	printf("%c", c);
}

//中序遍历二叉树 非递归
void InOrderTraverse(BiThrTree T)
{
	BiThrTree p;
	p = T -> lchild;
	while(p != T)
	{
		while(p -> ltag == Link)
		{
			p = p -> lchild;
		} 
		visit(p -> data);
		
		while(p -> rtag == Thread && p -> rchild != T)
		{
			p = p -> rchild;
			visit(p -> data);
		}
		p = p -> rchild;
	}
}

4.在这里插入图片描述
5.输出结果
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值