二叉树的先序、中序、后序遍历方法(递归与非递归方法)——《数据结构》

// 二叉树的三种遍历方法(终结版)
#include<stdio.h>
#include<stdlib.h>

typedef struct Bitree
{
	int data;
	struct Bitree *lchild,*rchild;
}BitreeNode,*LinkBitree;

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

LinkBitree CreatBitree();

StackList InitStack();


void preordertraverse(LinkBitree);
void Inordertraverse(LinkBitree);
void Postordertraverse(LinkBitree) ;

//int preordertraverse(LinkBitree);
//int Inordertraverse(LinkBitree);
//int Postordertraverse(LinkBitree) ;


int visit(int);

int main()
{
	LinkBitree BitreeHead;	
	printf("请输入根结点的值:e=  ");
	BitreeHead=CreatBitree();
	//StackList Stack;
	//Stack=InitStack(); //换做在遍历的时候初始化
	preordertraverse(BitreeHead);
	Inordertraverse(BitreeHead);
	Postordertraverse(BitreeHead);
	return 0;
}

LinkBitree CreatBitree()
{
	int edata;
	LinkBitree Head;
	scanf("%d",&edata);
	if(edata==0)
	{
		Head=NULL;
	}
	else
	{
		Head=(LinkBitree)malloc(sizeof(BitreeNode));
	    if(Head==NULL)
		{
			printf("内存分配失败!!");
		    exit(0);
		}
		else
		{
			Head->data=edata;
			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 preordertraverse(LinkBitree Head)
{
	

	StackList Stack;
	Stack=InitStack(); // 初始化栈
	printf("先序遍历结果\n");
	
	do
	{
		while(Head)//先序遍历,一直到最左下的位置
		{
			visit(Head->data);
			Stack->data[Stack->top]=Head;//入栈
			Stack->top=Stack->top+1;
			Head=Head->lchild;
		}

		if(Stack->top)//栈不为空
		{
			Stack->top--;
			Head=Stack->data[Stack->top]; //出栈
			Head=Head->rchild;
		}
	}while(Stack->top||Head); 

	printf("\n\n");
}

/* //递归访问程序
int preordertraverse(LinkBitree T)
{
	printf("先序遍历结果\n");
	if(T)
	{
	 if(visit (T->data))
		 if(preordertraverse(T->lchild))
			 if(preordertraverse(T->rchild)) return 1;
			 
	 return 0; // 实际上,无论访问哪个结点,都不会输出0,对于空指针,直接返回1 对于 非空指针,递归访问其左子树右子树
	}
	else
		return 1; //访问到根节点的左右子树,返回1
		printf("\n\n");
}*/


void Inordertraverse(LinkBitree Head) //非递归中续遍历
{
	StackList Stack;
	Stack=InitStack(); // 初始化栈	
	printf("遍历结果\n");

	do
	{
		while(Head)//先序遍历,一直到最左下的位置
		{
			Stack->data[Stack->top]=Head;//入栈
			Stack->top=Stack->top+1;
			Head=Head->lchild;
		}
		
		if(Stack->top)//栈不为空
		{
			Stack->top--;
			Head=Stack->data[Stack->top]; //出栈
			visit(Head->data);
			
			Head=Head->rchild;
		}
	}while(Stack->top||Head); 
	
	printf("\n\n");
}

//递归访问程序 中序遍历
/*int Inordertraverse(LinkBitree T)
{
	

	if(T)
	{
	 if(Inordertraverse(T->lchild))
	   if(visit (T->data))
		if(Inordertraverse(T->rchild)) return 1;
			 
	 return 0; // 实际上,无论访问哪个结点,都不会输出0,对于空指针,直接返回1 对于 非空指针,递归访问其左子树右子树
	}
	else
		return 1; //访问到根节点的左右子树,返回1

}*/

/*
实现二叉树的后序遍历二叉树后序遍历的思想:
从根节点开始,沿左子树一直走到没有左孩子的节点为止,并将所经[节点]的地址第一次进栈;当找到没有左孩子的节点时,此节点的左子树已访问完毕;
从栈顶退出该节点,判断该节点是否为第一次进栈,如是,再将所经[节点]的地址第二次进栈,并沿该节点的右子树一直走到没有右孩子的节点为止,如否,则访问该节点;此时,该节点的
左、右子树都已完全遍历,且令指针p = NULL;
如此重复到栈空为止。
 */
void Postordertraverse(LinkBitree Head_m) //非递归后续遍历
{
	StackList Stack;
	int Tag[40];      //栈,用于标识结点的进栈次数
	LinkBitree Head = Head_m;
	Stack=InitStack(); // 初始化栈

	printf("后序遍历结果\n");
	
	do
	{
		while(Head)//先序遍历,一直到最左下的位置
		{
			Stack->data[Stack->top]=Head;//入栈
			Tag[Stack->top] = 0; // 注意栈中i个元素与Tag中第i+1个元素对应
			Stack->top=Stack->top+1;			
			Head=Head->lchild;
		}
		
		Stack->top = Stack->top -1 ;
		Head=Stack->data[Stack->top]; //出栈
		

		if(0 == Tag[Stack->top])//如果该结点是第1次进栈
		{

			Stack->data[Stack->top]=Head;//再次入栈
			Tag[Stack->top] = 1;
			Stack->top=Stack->top+1;

			Head=Head->rchild; // 搜索该结点的右子树
			
		}
		else
		{
			//Stack->top--;
			//Head=Stack->data[Stack->top]; //if之前已经出栈过了
			visit(Head->data);
			Tag[Stack->top] = 0;
			Head = NULL; //这是程序退出的条件之一,也不会再次经过while(Head)
		}

	}while(Stack->top||Head); 
	
	printf("\n\n");
}
/*
//递归访问程序 后序遍历
int Postordertraverse(LinkBitree T)
{
	
	if(T)
	{
		if(Postordertraverse(T->lchild));		
		if(Postordertraverse(T->rchild));
		if (visit (T->data))
		return 1;
	
		return 0; // 实际上,无论访问哪个结点,都不会输出0,对于空指针,直接返回1 对于 非空指针,递归访问其左子树右子树
	}
	else
		return 1; //访问到根节点的左右子树,返回1	
}
*/




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值