线索二叉树的建立与遍历(C语言)

当我们建立普通的二叉树时,无法找到它的前驱与后继结点,而通过线索化二叉树,我们则可以轻松实现以上算法。

此处通过建立中序线索二叉树而实现了中序遍历。

代码如下:

#include<stdio.h>
#include<stdlib.h>

typedef struct Node
{
	char data;
	struct  Node* LChild, * RChild;
	int Ltag, Rtag;  //1表示前驱或后继
}BiNode, * BiTree;

BiTree CreateTree();      //建立二叉树
void Inthread(BiTree T, BiTree& pre);  //中序线索化二叉树
void PreThread(BiTree T, BiTree& pre);   //先序线索化二叉树
void PostThread(BiTree T, BiTree& pre);   //后序线索化二叉树
BiTree InPre(BiTree T);   //在中序二叉树寻找特定结点T前驱
BiTree InNext(BiTree T);  //在中序二叉树寻找特定结点T后继
BiTree InFirst(BiTree T); //找到中序线索化二叉树的第一个遍历结点
void InOrder(BiTree T);   //遍历中序线索化二叉树



int main()
{
	BiTree T;
	T = CreateTree();
	InOrder(T);
	return 0;
}

BiTree CreateTree()
{   //建立二叉树
	char ch;
	ch = getchar();
	BiTree T;
	if (ch == '#') {
		return NULL;
	}
	else {
		T = (BiTree)malloc(sizeof(BiNode));
		if (T == NULL) {
			printf("error1\n");
			return NULL;
		}
		T->data = ch;
		T->Ltag = 0;
		T->LChild = CreateTree();
		T->Rtag = 0;
		T->RChild = CreateTree();
	}
	return T;
}

void Inthread(BiTree T, BiTree& pre)
{   //中序线索化二叉树
	//与中序遍历普通二叉树做法基本一致
	if (T != NULL) {
		Inthread(T->LChild, pre);
		if (T->LChild == NULL) {
			T->Ltag = 1;
			T->LChild = pre;
		}
		if (pre != NULL && pre->RChild == NULL) {
			pre->RChild = T;
			pre->Rtag = 1;
		}
		pre = T;
		Inthread(T->RChild,pre);
	}
}

void PreThread(BiTree T, BiTree &pre)
{   //先序线索化二叉树
	if (T != NULL) {
		if (T->LChild == NULL) {
			T->Ltag = 1;
			T->LChild = pre;
		}
		if (pre != NULL && pre->RChild == NULL) {
			pre->RChild = T;
			pre->Rtag = 1;
		}
		pre = T;
		PreThread(T->LChild, pre);
		PreThread(T->RChild, pre);
	}
}

void PostThread(BiTree T, BiTree &pre)
{   //后序线索化二叉树
	if (T != NULL) {
		PostThread(T->LChild, pre);
		PostThread(T->RChild, pre);
		if (T->LChild == NULL) {
			T->Ltag = 1;
			T->LChild = pre;
		}
		if (pre != NULL && pre->RChild == NULL) {
			pre->RChild = T;
			pre->Rtag = 1;
		}
		pre = T;
	}
}

BiTree InPre(BiTree T)
{   //在中序二叉树寻找特定结点T前驱
	//对中序线索化二叉树,其前驱结点一定在其左子树方向
	BiTree pre, tmp;
	if (T->Ltag == 1) {
		pre = T->LChild;
	}
	else {
		for (tmp = T->LChild; tmp->Rtag == 0; tmp = tmp->RChild);
		pre = tmp;
	}
	return pre;
}

BiTree InNext(BiTree T)
{   //在中序二叉树寻找特定结点T后继
	//中序线索化二叉树,其后继结点一定是其右子树或其右子树的左子树方向
	BiTree next, tmp;
	if (T->Rtag == 1) {
		next = T->RChild;
	}
	else {
		if (T->RChild == NULL) {
			return NULL;
		}
		for (tmp = T->RChild; tmp->Ltag == 0; tmp = tmp->LChild);
		next = tmp;
	}
	return next;
}

BiTree InFirst(BiTree T)
{   //找到中序线索化二叉树的第一个遍历结点
	BiTree tmp;
	tmp = T;
	if (!tmp) {
		return NULL;
	}
	while (tmp->Ltag == 0) {
		tmp = tmp->LChild;
	}
	return tmp;
}

void InOrder(BiTree T)
{   //遍历中序线索化二叉树
	BiTree pre = NULL;
	Inthread(T, pre);
	BiTree tmp;
	tmp = InFirst(T);
	while (tmp) {
		printf("%c", tmp->data);
		tmp = InNext(tmp);
	}
}

运行截图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值