二叉树线索化仍不能解决的两个问题及原因

线索二叉树 结点结构定义如下:

若结点有左子树,则LChild域仍指向其左孩子;
否则,LChild域指向其某种遍历序列中的直接前驱结点。

若结点有右子树,则RChild域仍指向其右孩子;
否则,RChild域指向其某种遍历序列中的直接后继结点。

Ltag
0: LChild域指示结点的左孩子
1: LChild域指示结点的遍历前驱

Rtag
0: RChild域指示结点的右孩子
1: RChild域指示结点的遍历后继

线索二叉树的结点结构:在这里插入图片描述


线索二叉树


二叉树的中序线索化

void Inthread(BiTree root)
{	if(root!=NULL)
	{
		Inthread(root->LChild);/*线索化左子树*/
		if(root->LChild == NULL)
		{
			root->LChild = pre;
			root->Ltag = 1;		/*置前驱线索*/
		}
		if(pre != NULL && pre->RChild == NULL)
		{
			pre->RChild = root;
			pre->Rtag = 1;		/*置后继线索*/
		}
		pre = root;		/*记录当前访问结点,将成为下一个访问节点的前驱*/
		Inthread(root->LChild);/*线索化右子树*/
	}
}

先序、后序线索化也类似。(中序用的较多)

在线索二叉树中查找前驱和后继结点

eg 二叉树在线索化后,仍不能有效求解的问题是(D)

A先序线索二叉树中求先序后继

B中序线索二叉树中求中序后继

C中序线索二叉树中求中序前驱

D后序线索二叉树中求后序后继

先序遍历(中左右)、中序遍历(左中右)的最后访问的节点都是左或右叶节点,叶节点是没有子树的,所以两个指针域空出来了,可以存放线索指针。但是后续遍历(左右中),最后访问的是子树的根节点,而子树根节点的两个指针域都指向子树了,所以不能空出来存放线索信息。

线索二叉树有三种类型,分别为先序、中序、后序。

利用建立的线索二叉树找某个节点的前驱或者后继,仍不能有效解决先序线索二叉树找先序前驱和后序线索二叉树找后序后继。
在这里插入图片描述
先序遍历:A->B->D->E->C->F->G
中序遍历:D->B->E->A->F->C->G
后序遍历:D->E->B->F->G->C->A
A选项:
A->B->D这串可以从子指针得到
D->E->C由于子指针是空的,可以从子指针生成线索
C->F->G由上可得
B选项:同A,可以从空指针和子指针生成线索
C选项:同A
D选项:
C->A是不可能达到,因为C的左右儿子都是满的,已经没有地方存线索,所以不可能线索化

每个节点中存着自己的值,左孩子或者直接前驱和右孩子或者直接后继,我们从每个节点只能向下查找来找直接前驱或者直接后继,时间复杂度为O(n)。

若去遍历该节点的祖先节点,也可以找到先序的直接前驱和后序的直接后继,但是不建立线索二叉树通过遍历也可以找到它的直接前驱和直接后继,这两种情况就不用用线索二叉树去考虑了。所以线索二叉树不能有效解决先序线索二叉树找先序前驱和后序线索二叉树找后序后继。

**

4种可行情况代码

**

/*先序线索二叉树找后继*/
BiThrTree PreNext(BiThrThee p)
{
	if(p->Rtag == 1)
		next = p->RChild;
	else if(p->LChild){
        next = p->LChild;
    }else{
        next = p->RChild;
    }
	return next;
}
/*中序线索二叉树找前驱*/
BiThrTree InPre(BiThrThee p)
{
	if(p->Ltag == 1)
		pre = p->LChild;
	else{
		for(q=p->LChild;q->Rtag==0;q=q->RChild)
			pre = q;
	}
	return pre;
}
/*中序线索二叉树找后继*/
BiThrTree InNext(BiThrThee p)
{
	if(p->Rtag == 1)
		next = p->RChild;
	else{
		for(q=p->RChild;q->Ltag==0;q=q->LChild)
			next = q;
	}
	return next;
}
/*后序线索二叉树找前驱*/
BiThrTree PostPre(BiThrThee p)
{
	if(p->Ltag == 1)
		pre = p->LChild;
	else if(p->RChild){
		pre = p->RChild;
	}else{
		pre = p->LChild;
	}
	return pre;
}
  • 23
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值