C语言线索二叉树的实现

        线索二叉树的主要操作,包含:以p为根节点的子树中序线索化,带头结点的二叉树中序线索化和遍历线索二叉树这几个函数。

        下面讲一下实现代码:           

        首先,依然是类型定义,并声明一个全局变量pre:

typedef char ElemType;
typedef struct BiThrNode{
	ElemType data;
	BiThrNode *lchild, *rchild;
	int LTag, RTag;
}BiThrNode,*BiThrTree;
BiThrTree pre;

        带头结点的二叉树中序线索化:

BiThrNode *InOrderThreading(BiThrTree T)
{
	BiThrTree Thrt, p;
	Thrt = (BiThrNode *)malloc(sizeof(BiThrNode));
	Thrt->LTag = 0;
	Thrt->RTag = 1;
	Thrt->rchild = Thrt;
	if (!T)
		Thrt->lchild = Thrt;
	else
	{
		Thrt->lchild = T;
		pre = Thrt;
		InThreading(T);
		Thrt->rchild = pre;
		pre->RTag = 1;
		pre->rchild = Thrt;
	}
	return Thrt;
}

        先为Thrt动态分配空间,并让Thrt->LTag=0,Thrt->Rtag=1,让Thrt的右子树指向自己。判断二叉树T是否为空树,如果为空树,则让Thrt的左子树也指向自己;否则,让其左子树指向T的根节点,并且让全局变量pre=Thrt,线索化T(利用InThreading(),下面会提供代码)。注意线索化之后Thrt的右子树指向的是二叉树T最左端的节点,pre指向的是T最右端的节点且pre的RTag尚未赋值,pre的rchild并未指向任何位置。所以让Thrt的右子树指向pre节点,让pre->Rtag=1,pre的右节点指向Thrt.最后返回Thrt的值作为树的头节点。

        以p为根节点的子树中序线索化:

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

        先判断p子树是否为空,如果不为空,利用递归对p的左子树进行线索化。如果p的左子树为空,则让p->LTag为1,表示指向p的前驱,并且让pre赋值给p的右子树;如果不为空,则让p->LTag为0,表示指向p的后继。对pre进行同理操作。最后让pre移动到p的位置,并利用递归对p的右子树进行线索化。

        遍历线索二叉树:

void InOrderTraverse_Thr(BiThrTree T)
{
	BiThrTree p;
	p = T->lchild;
	while (p != T)
	{
		while (p->LTag == 0)
			p = p->lchild;
		printf("%c", p->data);
		while (p->RTag == 1 && p->rchild != T)
		{
			p = p->rchild;
			printf("%c", p->data);
		}
		p = p->rchild;
	}
	printf("\n");
}

        先声明一个指针p,让p指向T的左子树。当p不为T的时候,则执行以下循环:当p->LTag等于0的时候,表示p的左子树不为空,则一直循环让p指向p的左子树,让p到达T最左端的叶子。输出p的data数据。然后当p->Rtag等于1并且p的右子树不等于T的时候表示p有后继并p的右子树指向其后继,此时让p移动到p的右子树的位置,输出p的data数据。让p移动到p的右子树位置。自此最外的循环结束。

        创建新二叉树

BiThrNode *CreateBiTree(BiThrTree T)
{
	ElemType ch;
	scanf("%c", &ch);
	if (ch == '#')
		T = NULL;
	else
	{
		T = (BiThrNode *)malloc(sizeof(BiThrNode));
		T->data = ch;
		T->lchild = CreateBiTree(T->lchild);
		T->rchild = CreateBiTree(T->rchild);
	}
	return T;
}

        加入main()测试:

int main(void)
{
	BiThrTree T;
	int n;
	T = NULL;
	printf("1.创建二叉树\n2.转换为逻辑树\n3.遍历二叉树(按逻辑结构)\n");
	while (1)
	{
		printf("请选择:");
		scanf("%d", &n);
		fflush(stdin);
		switch (n)
		{
		case 1:
			T = CreateBiTree(T);
			break;
		case 2:
			T = InOrderThreading(T);
			break;
		case 3:
			InOrderTraverse_Thr(T);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值