二叉树的线索化

 【版权声明:转载请保留出处:blog.csdn.net/algorithm_only。邮箱:liuy0711@foxmail.com

前面说到二叉树的二叉链表表示实现,当以二叉树作为存储结构时,只能找到节点的左右孩子信息,不能直接得到结点在任一序列中的前驱和后继信息,只有在遍历过程中才能得到这种信息。我们知道,在n个结点的二叉链表栈必定存在n+1个空链域,因此,可以利用这些空链域来存放这些结点信息。所以作如下规定:若结点右左子树,则其lchild域指向其左孩子,否则令lchild域指向其前驱;若结点有右子树,其rchild域指向其右孩子,否则指向其后继。以这种结构构成的二叉链表叫做线索链表。

  • 线索链表的存储结构
typedef enum {link, thread}	pointer_tag;
typedef struct tnode {
	elemtype		data;
	struct tnode		*lchild, *rchild;
	pointer_tag		ltag, rtag;
}bithrnode, *bithrtree;
  • 二叉树的线索化(中序线索化)
int inorder_threading(bithrtree *thrt, bithrtree bt)
{
	*thrt = (bithrtree) malloc (sizeof(bithrnode));
	if (!*thrt)
		exit(OVERFLOW);
                                                   /* 将头结点线索化 */
	(*thrt)->ltag = link;
	(*thrt)->rtag = thread;
	(*thrt)->rchild = (*thrt);

	if (!bt)                                     /* 若二叉树为空,则将lchild指向自己 */
		(*thrt)->lchild = (*thrt);
	else {
		(*thrt)->lchild = bt;                   /* 头结点左指针指向根结点 */
		pre = (*thrt);
		in_threading(bt);                       /* 中序遍历进行中序线索化 */
		pre->rchild = *thrt;
		pre->rtag = thread;
		(*thrt)->rchild = pre;
	}
	return OK;
}
void in_threading(bithrtree t)
{
	if (t) {
		in_threading(t->lchild);

		if (!t->lchild) {
			t->ltag = thread;
			t->lchild = pre;
		}
		if (!pre->rchild) {
			pre->rtag = thread;
			pre->rchild = t;
		}
		pre = t;
		in_threading(t->rchild);
	}
}
线索化的实质是将二叉链表中的空指针改为指向前驱或后继的线索,前驱和后继的信息是在遍历过程中才能得到,故线索化的过程即为在遍历过程中修改空指针的过程。
  • 线索二叉树的遍历(中序)
int inorder_traverse_thr(bithrtree thrt, int (*visit)(bithrtree t))
{
	bithrtree		p;

	p = thrt->lchild;
	while (p != thrt) {
		while (p->ltag == link)
			p = p->lchild;
		visit(p);

		while (p->rtag == thread && p->rchild != thrt) {
			p = p->rchild;
			visit(p);
		}
		p = p->rchild;
	}
	return OK;
}
  • 总结
在中序线索二叉树上遍历二叉树,虽然时间复杂度任然为O(n),但相比上节所讲遍历算法,不需要栈和队列等辅助空间。
  • 算法实现源码
  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值