C语言数据结构之线索二叉树详细解析

线索二叉树

1.线索二叉树综述

引入线索二叉树是为了加快查找结点前驱和后继的速度
在有N个结点的二叉树中,有N+1个空指针,推导过程如下:
已知N0=N2+1 其中N0为度为0的结点,N2是度为2的结点
总的空指针=2N0+N1
因为:N0=N2+1
所以 总的空指针数=N0+N1+N2+1=N+1

线索化时规定:若无左子树,令lchild指向其前驱结点,若无右子树,则令rchild指向其后继节点,另许增加两个标志域表明当前指针所指对象是指向左(右)子结点还是前驱(后继)。
线索二叉树的结构体如下:

typedef struct ThreadNode{
	ElemType data;
	struct ThreadNode *lchild;
	struct ThreadNode *rchild;
	int ltag; 		//0表示其lchild指向左孩子,1表示指向其前驱
	int rtag;		//0表示rchild指向结点的右孩子,1表示指向结点的后继
}ThreadNode,*ThreadTree;

以这种结构构成的二叉树称为线索二叉树,对二叉树以某种次序遍历使其变成线索二叉树的过程称为线索化。

2.线索二叉树的构造

二叉树的线索化,实际上就是对二叉树进行一次遍历,只是在便利的时候,检查当前节点的左右指针域是否为空,若为空,将它们改为指向前驱结点或者后继节点的线索。
线索二叉树
通过中序遍历对二叉树线索化的递归算法如下:

void InThread(ThreadTree &p,ThreadTree &pre){
	if(p!=NULL){
		InThread(p->lchild,pre);			//pre表示中序遍历时,上一个刚刚访问的结点
		if(p->lchild==NULL){
			p->lchild=pre;
			p->tag=1;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->rchild=p;
			pre->rtag=1;
			}
		pre=p;
		InThread(p->rchild,pre);
	}
}

通过中序遍历建立中序线索二叉树的主过程算法如下:

void CreateInThread(ThreadTree T){
	ThreadTree pre=NULL;
	if(T!=NULL){						//非空
		InThread(T,pre);				//线索化二叉树
		pre->rchild=NULL;			//处理遍历的最后一个结点
		pre->rtag=1;
		}
}

有时候为了方便,仿照线性表的存储结构,在二叉树的线索链表上也加上一个头结点,并令其lchild指向根结点,rchild指向中序遍历时访问的最后一个结点,反之,令中序遍历的第一个节点的lchild域的指针和最后一个结点rchild域的指针均指向头结点,这好比建立双向线索链表,可以从第一个结点开始,也可以从最后一个结点开始。
带头结点的二叉树如图所示:
带头结点的线索二叉树

3.线索二叉树的遍历

线索二叉树的结点中隐含了线索二叉树的前驱后继节点,利用线索二叉树,可以实现二叉树的非递归算法。
1.中序线索二叉树中,中序序列下的第一个节点。

ThreadNode *FirstNode(ThreadNode *p){
	while(p->ltag==0){
		p=p->lchild;      //最左下结点
	}
	return p;
}

2.中序线索二叉树中结点p在中序序列下的后继节点。

ThreadNode *NextNode(ThreadNode *p){
	if(p->rtag==0)
		return FirstNode(p->rchild);
	else
		return p->rchild;
}

3.中序遍历

void InOrder(ThreadNode *T){
	for(ThreadNode *p=FirstNode(T);p!=NULL;p=NextNode(p))
		visit(p);
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值