二叉树:三种非递归遍历(迭代)

 后序非递归遍历,需要加标记,还需要对有右子树的节点进行两次入栈操作,这是不同的

void InorderTraversal(BinTree BT) {
	if ( !BT ) return;
	BinTree tt = BT;
	Stack s = CreateStack();
	while ( tt || !IsEmpty(s) )
	{
		while ( tt )
		{
			Push(s, tt);
			tt = tt->Left;
		}
//一路向左,压入节点到栈中。然后输出第一个要被输出的左节点tt,然后tt父亲节点的右节点
		tt = Pop(s);
		printf(" %c", tt->Data);
		tt = tt->Right;
	}
}
void PreorderTraversal(BinTree BT) {
	if ( !BT ) return;
	BinTree tt = BT;
	Stack s = CreateStack();
	while ( tt || !IsEmpty(s) )
	{
		while ( tt )
		{
			printf(" %c", tt->Data);
			Push(s, tt);
			tt = tt->Left;
		}
		tt = Pop(s);
		//printf("%d ", tt->Data);
		tt = tt->Right;
	}
}
void PostorderTraversal(BinTree BT) {
	if ( !BT ) return;
	BinTree tt = BT;
	Stack s = CreateStack();
	BinTree flag = NULL;
//flag的必要性:
	while ( tt || !IsEmpty(s) )
	{
		while ( tt )
		{
			Push(s, tt);
			tt = tt->Left;  
		}
		if ( !IsEmpty(s) ) {
			tt = Pop(s);
			if ( tt->Right && tt->Right != flag )
			{
				Push(s, tt);
				tt = tt->Right;

//某个节点转向他的右节点的时候,把右边访问完了,需要访问这右边(右子树的根节点)
//如果不加以标记说这个右边的子树访问过了,那么节点又要转向右边的节点。可以自己画图理解,模拟代码操作
			}
			else {
				printf(" %c", tt->Data);
				flag = tt;
				tt = NULL;
			}
		}
	}
}

posted @ 2022-11-02 00:27  noob-lian  阅读(23)  评论(0)    收藏  举报
Language: