10.树.线索二叉树

线索二叉树

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

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef char TElemType;//TElemType这里假设为char,可以根据需要进行更改
typedef int Status;//Status是函数的类型,其值是函数结果状态代码,如OK等

typedef enum {Link,Thread} PointerTag;//Link==0表示指向左右孩子指针,Thread==1表示指向前驱或后继的线索

//结点结构
typedef struct biThrNode
{
	TElemType data;//结点数据
	struct biThrNode *lchild,*rchild;//左右孩子指针
	PointerTag LTag,RTag;//左右标志
}BiThrNode;

int index=0;
char String[]="ABDH##I##EJ###CF##G##";//前序后的输入字符 

Status visit(TElemType e)
{
	printf("%c ",e);
	return OK;
}

/*按前序输入二叉线索树中结点的值,构造二叉线索树T*/
Status CreateBiThrTree(BiThrNode **T)
{
	TElemType ch;
	ch=String[index++];

	if(ch=='#')
		*T=NULL;
	else
	{
		*T=(BiThrNode *)malloc(sizeof(BiThrNode));
		if(!(*T))
			exit(OVERFLOW);
		(*T)->data=ch;//生成根结点(前序)

		CreateBiThrTree(&(*T)->lchild);//构造左子树
		if((*T)->lchild)//有左孩子
			(*T)->LTag=Link;

		CreateBiThrTree(&(*T)->rchild);//构造右子树
		if((*T)->rchild)
			(*T)->RTag=Link;
	}

	return OK;
}

BiThrNode *pre;//全局变量,始终指向刚刚访问过的结点

/* 中序遍历进行中序线索化 */
void InThreading(BiThrNode *p)
{ 
	if(p)
	{
		InThreading(p->lchild);//递归左子树线索化

		if(!p->lchild)//没有左孩子
		{
			p->LTag=Thread;//前驱线索
			p->lchild=pre;//左孩子指针指向前驱
		}

		if(!pre->rchild)//前驱没有右孩子
		{
			pre->RTag=Thread;//后继线索
			pre->rchild=p;//前驱右孩子指针指向后继(当前结点p)
		}

		pre=p;//保持pre指向p的前驱
		InThreading(p->rchild);//递归右子树线索化
	}
}

/*中序遍历二叉树T,并将其中序线索化,Thrt指向头结点*/
Status InOrderThreading(BiThrNode **Thrt,BiThrNode *T)
{
	*Thrt=(BiThrNode *)malloc(sizeof(BiThrNode));//建头结点
	if(!(*Thrt))
		exit(OVERFLOW);
	(*Thrt)->LTag=Link;
	(*Thrt)->RTag=Thread;
	(*Thrt)->rchild=*Thrt;//右指针回指

	if(!(T))//若二叉树空,则左指针回指
		(*Thrt)->lchild=*Thrt;
	else
	{
		(*Thrt)->lchild=T;//头结点左孩子指向根节点
		pre=(*Thrt);//pre指向头结点

		InThreading(T); /* 中序遍历进行中序线索化 */

		pre->RTag=Thread;
		pre->rchild=*Thrt;//最后一个结点线索化,指向头结点
		(*Thrt)->rchild=pre;//头结点线索化,指向最后一个结点
	}

	return OK;
}

/*中序遍历二叉线索树T(头结点)的非递归算法*/
Status InOrderTraverse_Thr(BiThrNode *T)
{ 
	BiThrNode *p;
	p=T->lchild;//p指向根结点
	while(p!=T)
	{//空树或遍历结束时,p==T
		while(p->LTag==Link)
			p=p->lchild;
		if(!visit(p->data))//访问其左子树为空的结点
			return ERROR;
		while(p->RTag==Thread&&p->rchild!=T)//有后继线索则直接指向后继结点
		{
			p=p->rchild;
			visit(p->data);//访问后继结点
		}
		p=p->rchild;//进入右子树
	}
	return OK;
}

int main()
{
	BiThrNode *t,*h;//t指向根节点,h指向头结点
	PointerTag P;

	printf("请按前序输入二叉树(如:'ABDH##I##EJ###CF##G##')\n");
	CreateBiThrTree(&t);

	InOrderThreading(&h,t); /* 中序遍历,并中序线索化二叉树 */
	
	InOrderTraverse_Thr(h); /* 中序遍历(输出)二叉线索树 */
	printf("\n");

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值