二叉树:三种非递归遍历(迭代)
后序非递归遍历,需要加标记,还需要对有右子树的节点进行两次入栈操作,这是不同的
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;
}
}
}
}

浙公网安备 33010602011771号