二叉树的前序中序线索化及对对应线索二叉树的遍历

《数据结构》

最近在看数据结构,这里给下我自己弄的程序(当然是参考书上的了)

对二叉树的线索化分前序和中序两种,分别给出了递归与非递归的方法。

对于后序线索二叉树的遍历还有些问题。(其实是后序线索二叉树太鸡肋了,我感觉没啥用)

// 二叉树的线索化与遍历

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

typedef struct BiThrNode
{
	int data;
	struct BiThrNode *Lchild,*Rchild;
	int Ltag, Rtag; //线索标志0,表示孩子结点 1表示前驱或后继结点
}BiThrNode,*BiThrBitree;

typedef struct Stack
{
	BiThrBitree data[40];
	int top,bottom;
}Stack,*StackList;


BiThrBitree CreatBitree();
StackList InitStack();

void PreThreading(BiThrBitree);
//void InThreading(BiThrBitree);
//void PostThreading(BiThrBitree);
BiThrBitree OrderThreading(BiThrBitree);
void PreorderTraverse_Thr(BiThrBitree);
//void InorderTraverse_Thr(BiThrBitree);
//void PostorderTraverse_Thr(BiThrBitree);

BiThrBitree pre;

int main()
{
	BiThrBitree BitreeHead, T;
	printf("请输入根结点的值:e=  ");
	BitreeHead = CreatBitree();
	T = OrderThreading(BitreeHead);
	//PreorderTraverse_Thr(T);
	//InorderTraverse_Thr(T);
	PostorderTraverse_Thr(T);
	return 0;
}

BiThrBitree CreatBitree()
{
	int edata;
	BiThrBitree Head;
	scanf("%d",&edata);
	if(edata==0)
	{
		Head=NULL;
	}
	else
	{
		Head=(BiThrBitree)malloc(sizeof(BiThrNode));
		if(Head==NULL)
		{
			printf("内存分配失败!!");
			exit(0);
		}
		else
		{
			Head->data=edata;
			Head->Ltag = Head->Rtag = 0; //初始化为0
			printf("请输入结点%d的左孩子的值:e= ",Head->data);
			Head->Lchild=CreatBitree();
			printf("请输入结点%d的右孩子的值:e= ",Head->data);
			Head->Rchild=CreatBitree();
		}
	}
	return Head;
}

StackList InitStack()
{
	StackList Stack;
	Stack=(StackList)malloc(sizeof(Stack));
	if(Stack==NULL)
	{
		printf("内存分配失败!!");
		exit(0);
	}
	else
	{
		Stack->top=0;
		Stack->bottom=0;
	}
	return Stack;
}


int visit(int a)
{
	printf("%5d",a);
	
	return 1;
}

void PreThreading(BiThrBitree Head)//先序遍历的递归算法 将二叉树线索化
{
	if(Head)
	{
		if(!Head->Lchild){Head->Ltag=1; Head->Lchild = pre;}//处理该结点
		if(!pre->Rchild){pre->Rtag = 1; pre->Rchild = Head;}
		pre=Head;

		//因为先序是先处理根结点,如果前面已补充了根节点的前驱,使得Head->Lchild不为空,会造成死循环
		if(!Head->Ltag)
			PreThreading(Head->Lchild); //处理左子树
		if(!Head->Rtag)
			PreThreading(Head->Rchild); //处理右子树

	}
	return;
}

/*
void PreThreading(BiThrBitree Head)//先序遍历的非递归算法 将二叉树线索化
{
	StackList Stack;
	Stack=InitStack(); 
	
	do
	{
		while(Head)
		{
			if(!Head->Lchild){Head->Ltag=1; Head->Lchild = pre;}//处理该结点
			if(!pre->Rchild){pre->Rtag = 1; pre->Rchild = Head;}
			pre=Head;
			Stack->data[Stack->top++] = Head; //入栈
			if(0==Head->Ltag)//先序遍历是先处理结点,在遍历左子树前要判断左孩子是前驱还是左子树
				Head = Head->Lchild;
			else break;

		}
		if(Stack->top)
		{
			Stack->top--;
			Head=Stack->data[Stack->top]; //出栈
			Head = Head->Rchild;
		}

	}while(Stack->top||Head);

}
*/

/*
void InThreading(BiThrBitree Head)//中序遍历的递归算法 将二叉树线索化
{
	
	if(Head){
		InThreading(Head->Lchild); //处理左子树	
		if(!Head->Lchild){Head->Ltag=1; Head->Lchild = pre;}//处理该结点
		if(!pre->Rchild){pre->Rtag=1; pre->Rchild = Head;}
		pre=Head;
		InThreading(Head->Rchild); //处理右子树

	}
	return;
}
*/
/*
void InThreading(BiThrBitree Head) //中序遍历的非递归算法,将二叉树线索化
{
	StackList Stack;
	Stack=InitStack(); 
	do
	{
		while(Head)
		{
			Stack->data[Stack->top++] = Head; //入栈
			Head = Head->Lchild;
		}
		if(Stack->top)
		{
		Head = Stack->data[--Stack->top];	  //出栈
		if(!Head->Lchild)	{Head->Ltag=1; Head->Lchild = pre;}//处理该结点
		if(!pre->Rchild)	{pre->Rtag=1; pre->Rchild = Head;}
		pre = Head;
		Head = Head->Rchild;
		}

	}while((Stack->top||Head));

}
*/

BiThrBitree OrderThreading(BiThrBitree Head)//二叉树的XX序遍历线索化
{
	//二叉树的线索表上添加了一个头结点Thrt,其Lchild域指针指向二叉树根节点,Rchild域指针指向中序遍历时访问的最后一个结点
	BiThrBitree Thrt;
	if(!(Thrt = (BiThrBitree)malloc(sizeof(BiThrNode)))) exit(1);
	Thrt->data = 0;
	Thrt->Ltag = 0; Thrt->Rtag = 1;//为了在第一判断的时候不改变根节点的右孩子值
	Thrt->Rchild = Thrt;

	if(!Head){Thrt->Lchild = Thrt;}
	else
	{
		Thrt->Lchild = Head; pre = Thrt;
		//PreThreading(Head);
		//InThreading(Head);
		PostThreading(Head);
		pre->Rchild = Thrt; pre->Rtag = 1; //最后一个结点的线索化
		Thrt->Rchild = pre;

	}
	
	return Thrt;

}

//线索二叉树注意问题:
//对于根节点,其左右子树再也不是NULL了,所以不能以head=NULL作为判断依据,如果按照以前的判断条件,一直遍历左子树将会得到死循环
void PreorderTraverse_Thr(BiThrBitree T)
{ // 对线索二叉树的先序遍历
	
	BiThrBitree Head;
	Head = T->Lchild;
	printf("先序遍历结果\n");
	while(Head!=T)
	{
		
		while(0==Head->Ltag&&Head)//先序遍历到左下角(head = 左下角的结点,此结点还未被访问)//0==Head->Ltag表示head存在左结点
		{	
			visit(Head->data);
			Head = Head->Lchild;
		}
	
			visit(Head->data);
			Head = Head->Rchild; //这儿无论后继还是右孩子都一样	
			
	}
	printf("\n\n");
}

/*
void InorderTraverse_Thr(BiThrBitree T){ // 对线索二叉树的中序遍历

	BiThrBitree Head;
	Head = T->Lchild;
	printf("中序遍历结果\n");	
	while(Head!=T)
	{


		while(0==Head->Ltag) //先找到最左下的结点
		{
			Head = Head->Lchild;
		}
		visit(Head->data);
		while(1==Head->Rtag&&Head->Rchild!=T) //如果Head的右子树为空,跳到其后继
		{
			Head = Head->Rchild;
			visit(Head->data);
		}
		Head = Head->Rchild; // 调到后继的右子树或者是head的右子树

	}
	printf("\n\n");
}
*/

如果大家感兴趣,我也做了下后序遍历的线索化,但是在编写后序线索二叉树的遍历程序时,蛋疼的发现后序遍历的线索二叉树真心废物一枚。

// 后序遍历线索化
/*
void PostThreading(BiThrBitree Head)//后遍历的递归算法 将二叉树线索化
{
	
	if(Head){
		PostThreading(Head->Lchild); //处理左子树	

		PostThreading(Head->Rchild); //处理右子树

		if(!Head->Lchild){Head->Ltag=1; Head->Lchild = pre;}//处理该结点
		if(!pre->Rchild){pre->Rtag = 1; pre->Rchild = Head;}
		pre=Head;

	}
	return;
}*/

/*
void PostThreading(BiThrBitree Head)//中序遍历的递归算法 将二叉树线索化
{
	StackList Stack;
	int Tag[40];
	Stack = InitStack();
	
	do
	{
		while(Head)
		{
			Stack->data[Stack->top] = Head; //入栈
			Tag[Stack->top] = 0;
			Stack->top++;
			Head = Head->Lchild;
		}

		Head = Stack->data[--Stack->top]; //出栈

		if(0==Tag[Stack->top])
		{
			Stack->data[Stack->top] = Head; //再次入栈
			Tag[Stack->top] = 1;
			Stack->top++;
			Head = Head->Rchild;
		}
		else
		{
			if(!Head->Lchild){Head->Ltag=1; Head->Lchild = pre;}//处理该结点
			if(!pre->Rchild){pre->Rtag = 1; pre->Rchild = Head;}
			pre=Head;	
			Head = NULL; //继续出栈
		}

	}while(Stack->top||Head)
	
}
*/
有问题请留言,欢迎讨论~~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值