线索二叉树的建立【代码分析】【中序遍历】

建立线索二叉树其实就是二叉树的线索化,在这里就不详细讲原理了,构建的方法书上都有,在这主要对代码分析。

首先先是对线索二叉树的声明:

#include<stdio.h>
typedef char ElemType;
typedef struct bthnode
{
	ElemType data;
	struct bthnode *lchild,rchild;
	int ltag,rtag;
}BthNode;

其中和二叉树不一样的地方就是多了两个整型的ltag和rtag,其实是为了区分左右结点是指向左右孩子还是指向前驱或者后继。

接下来我们首先创建一个头结点head,头结点的data域为空,只用他的左右孩子域:

BthNode *CreaThread(BthNode *bt)
{
	BthNode *head;
	head=(BthNode *)malloc(sizeof(BthNode));
	head->ltag=0;head->rtag=1;
	head->rchild=bt;

创建好之后将它右孩子域指向bt这个二叉树,先要判断若这个二叉树为空,则

{
		head->ltag=0;head->lchild=head; 
	    head->rtag=1;head->rchild=NULL;
	}

若不为空,将头结点的左孩子指向二叉树首结点。开始遍历;

重点来了!!!

我们把这个中序遍历法来插入线索的函数写出来。

BthNode *pre;
void Thread(BthNode *&p)
{
	if(p!=NULL)
	{
		Thread(p->lchild);
		if(p->lchild==NULL;)
		{
			p->lchild=pre;
			p->ltag=1;
		}
		else p->ltag=0;
		if(pre->rchild==NULL)
		{
			pre->rchild=p;
			pre->rtag=1; 
		}
		else pre->rtag=0;
		pre=p;
		Thread(p->rchild);
	}
}

先定义一个全局变量pre,它是p的前驱;然后在遍历函数中用p逐一从第一个开始按中序遍历顺序往后移动。当这个结点p不为空时开始执行。

Thread(p->lchild);就是一路向左,递归知道最后一个左孩子(叶子)找到,并对它经行线索化。一开始我们让pre指向头结点。以下图为例,中序遍历顺序:(DBEAC)

 p指向D,pre指向头结点:

 它的左孩子为空,则让它指向pre,并且ltag为1;

 它的pre右孩子不为空,则让rtag为0;

 之后将pre赋为p,因为D左右孩子都为空,所以Thread(p->lchild);和Thread(p->rchild);直接跳过。

            回到上一个递归,

p指向B,pre指向D:

B的左孩子域不为空,ltag=0;

B的pre右孩子域为空,D的右孩子域指向B,rtag=1;(表示的意思就是D的后继为B)

pre=p,对B->rchild(E)分析:

P指向E,pre指向B;

E的左孩子域为空,则让它指向pre(B)(意思就是表达E的前驱的B),ltag=1;

pre的右孩子不为空,rtag=0;(就是本来要表示B的后继是E,但B右孩子存了E,所以存不下了)

再重新pre=p,回到上一个递归.........................后面的都一样,就不一一说了。

这个函数写好后就开始调用它:完成最后的收尾工作:

else
	{
		head->lchild=bt;
		pre=head;
		Thread(bt);
		pre->rchild=head;
		pre->rtag=1;
		head->rchild=pre;
	}
	return head;//全部线索化好了,将头结点返回 
}

将遍历的最后一个结点的右孩子域指向头结点,将头结点的右孩子域指向最后一个结点(这时pre就是指向最后一个结点,因为函数结尾进行了赋值)。

最后整个代码如下:

#include<stdio.h>
typedef char ElemType;
typedef struct bthnode
{
	ElemType data;
	struct bthnode *lchild,rchild;
	int ltag,rtag;
}BthNode;
BthNode *CreaThread(BthNode *bt)
{
	BthNode *head;
	head=(BthNode *)malloc(sizeof(BthNode));
	head->ltag=0;head->rtag=1;
	head->rchild=bt;
	if(bt==NULL)
	{
		head->ltag=0;head->lchild=head; 
	    head->rtag=1;head->rchild=NULL;
	}
	else
	{
		head->lchild=bt;
		pre=head;
		Thread(bt);
		pre->rchild=head;
		pre->rtag=1;
		head->rchild=pre;
	}
	return head;//全部线索化好了,将头结点返回 
}
BthNode *pre;
void Thread(BthNode *&p)
{
	if(p!=NULL)
	{
		Thread(p->lchild);
		if(p->lchild==NULL;)
		{
			p->lchild=pre;
			p->ltag=1;
		}
		else p->ltag=0;
		if(pre->rchild==NULL)
		{
			pre->rchild=p;
			pre->rtag=1; 
		}
		else pre->rtag=0;
		pre=p;
		Thread(p->rchild);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>