线索二叉树

线索二叉树:

对于一个有n个结点的二叉链表,每个结点有指向左右孩子的两个指针域,所以一共是2n个指针域。而n个结点的二叉树一共有n-1条分支线,也就是说存在n+1个空指针域。

我们可以考虑利用那些空地址,存放指向结点在某种遍历次序下的前驱和后继结点的地址。

我们把这种指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树就称为线索二叉树。

我们对二叉树以某种次序遍历使其变为线索二叉树的过程称作是线索化。线索化的过程就是在遍历的过程修改空指针的过程。

其实线索二叉树,等于把一棵二叉树转变成了一个双向链表。


线索二叉树结构实现:

typedef enum {Link, Thread} PointerTag;
typedef struct BiThrNode
{
	TElemType data;
	struct BiThrNode *lchild, *rchild;
	PointerTag LTag;
	PointerTag RTag;
} BiThrNode, *BiThrTree;


中序遍历线索化的递归函数代码:

BiThrTree pre;
void InThreading(BiThrTree p)
{
	if (p)
	{
		InThreading(p->lchild);
		if (!p->lchild)
		{
			p->LTag = Thread;
			p->lchild = pre;
		}
		if (!pre->rchild)
		{
			pre->RTag = Thread;
			pre->rchild = p;
		}
		pre = p;
		InThreading(p->rchild);
	}
}

遍历线索二叉树:

在二叉树线索链表上添加一个头结点,并令其lchild域的指针指向二叉树的根结点,其rchild域的指针指向中序遍历访问的最后一个结点。反之,令二叉树的中序序列中的第一个结点中,lchild域指针和最后一个阶段的rchild域指针均指向头结点。这样定义的好处就是我们既可以从第一个结点其顺后继进行遍历,也可以从最后一个结点起顺前驱进行遍历。

Status InOrderTraverse_Thr(BiThrTree T)
{
	BiThrTree p;
	p = T->lchild;
	while (p != T)
	{
		while (p->LTag == Link)
			p = p->lchild;
		printf("%c", p->data);
		while (p->RTag == Thread && p->rchild != T)
		{
			p = p->rchild;
			printf("%c", p->data);
		}
		p = p->rchild;
	}
	return OK;
}

它等于是一个链表的扫描,所以时间复杂度为 O(n)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值