二叉树的创建与遍历2

//二叉树的非递归遍历 堆栈

堆栈 

中序遍历算法:

1.当遇到一个结点,就把它压栈,并去遍历他的左子树;
2.当左子树遍历结束后,从栈顶弹出这个结点并访问它;
3.然后按其有指针再去中序遍历该节点的右子树。
//用堆栈实现中序遍历的非递归程序
void InOrderTrversal(BinTree BT)
{
	BinTree Ptr = BT;
	Stack S = CreatStack(MaxSize);  //S为堆栈栈顶地址
	while(Ptr || !IsEmpty(S) )
	{
		while(Ptr)
		{
			Push(S,Ptr);
			Ptr = Ptr->Left;			
		}
		if(!IsEmpty(S))
		{
			Ptr = Pop(S);
			printf("%4d",Ptr->Data);
			Ptr = Ptr->Right;		
		}		
	}	
}	


先序遍历算法:同中序遍历算法

//用堆栈实现先序遍历的非递归程序
void PreOrderTrversal(BinTree BT)
{
	BinTree Ptr = BT;
	Stack S = CreatStack(MaxSize);  //S为堆栈栈顶地址
	while(Ptr || !IsEmpty(S) )
	{
		while(Ptr)
		{
			Push(S,Ptr);
			printf("%4d",Ptr->Data);
					//和中序操作基本一致,只是先序是在压栈时就读取数据
			Ptr = Ptr->Left;			
		}
		if(!IsEmpty(S))
		{
			Ptr = Pop(S);
			Ptr = Ptr->Right;		
		}		
	}	
}	


后序遍历算法:

//用堆栈实现后序遍历的非递归程序

void PostOrderTraversal( BinTree BT )
{
	BinTree Ptr = BT;
	Stack S = CreatStack( MaxSize ); /*创建并初始化堆栈S*/
	Stack Q = CreatStack( MaxSize ); /*创建并初始化堆栈Q,用于输出反向*/
	while( Ptr || !IsEmpty(S) )
	{
		while(Ptr)
		{ /*一直向右并将沿途结点压入堆栈*/
			Push(S,Ptr);
			Push(Q,Ptr);/*将遍历到的结点压栈,用于反向*/
			Ptr = Ptr->Right;
		}
		if(!IsEmpty(S))
		{
			Ptr = Pop(S); /*结点弹出堆栈*/
			Ptr = Ptr->Left; /*转向左子树*/
		}
	}
	while( !IsEmpty(Q) )
	{
		Ptr = Pop(Q);
		printf(“%5d”, Ptr->Data); /*(访问)打印结点*/
	}
}	


//关于后序遍历的非递归算法的比较好的理解,摘录自网络
先序的访问顺序是root, left, right 假设将先序左右对调,则顺序变成root, right, left,暂定称之为“反序”。 
后序遍历的访问顺序为left, right,root ,刚好是“反序”结果的逆向输出。于是方法如下:
1、反序遍历二叉树,具体方法为:将先序遍历代码中的left 和right对调即可;数据存在堆栈S中。
2、在先序遍历过程中,每次Push节点后紧接着print结点;对应的,在反序遍历时,将print结点改为把当前结点 PUSH到堆栈Q中。
3、反序遍历完成后,堆栈Q的压栈顺序即为反序遍历的输出结果。此时再将堆栈Q中的结果pop并print,即为“反序”结果的逆向,也就是后序遍历的结果。

4.后序的缺点是堆栈Q的深度等于数的结点数,空间占用较大。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值