第一种方法
二叉树的后序遍历算法比先序和中序的遍历算法要复杂一些。其出栈条件有两种情况:
栈顶元素所指向的节点的左子树和右子树均为空;
栈顶元素所指向的节点的左子树和右子树均被访问过。
第二种情况,加一个指针pre,来纪录此节点是否被访问过了,进栈顺序是先进右子树,再进左子树
void PostOrderNor(BTNode* Root)
{
Stack s;
StackInit(&s);
if (Root->data == '#')
return;
BTNode* pre = NULL;
BTNode* cur = NULL;
StackPush(&s, Root);
while (!StackEmpty(&s))
{
cur = StackTop(&s);
if (((cur->left)->data == '#' && (cur->right)->data == '#' )||
(pre != NULL &&(pre == cur->left || pre == cur->right)))
{
printf("%c ", cur->data);
StackPop(&s);
pre = cur;
}
else
{
if ((cur->right)->data != '#')
StackPush(&s, cur->right);
if ((cur->left)->data != '#')
StackPush(&s, cur->left);
}
}
StackDestroy(&s);
}
第二种方法
前序遍历为:根–左--右,后序遍历为:左–右--根, 后序遍历翻转一下就是:根–右--左,
我们可以将二叉树前序非递归遍历改一下,可以先进左子树,再进右子树,这样最后得出的结果就为:根–右--左,再将它逆向输出即为后序遍历;
void PostOrderNor(BTNode* Root)
{
Stack s;
StackInit(&s);
Stack s1;
StackInit(&s1);
if (Root->data == '#')
return;
StackPush(&s, Root);
while (!StackEmpty(&s))
{
BTNode* top = StackTop(&s);
StackPush(&s1, top);
StackPop(&s);
if ((top->left)->data != '#')
StackPush(&s, top->left);
if ((top->right)->data != '#')
StackPush(&s, top->right);
}
while (!StackEmpty(&s1))
{
printf("%c ", StackTop(&s1)->data);
StackPop(&s1);
}
StackDestroy(&s);
StackDestroy(&s1);
}
第三种方法
void PostOrderNor(BTNode* root)
{
BTNode* pCur = root;
BTNode* pPrev = NULL;
Stack s;
InitStack(&s);
while (pCur || !EmptyStack(&s))
{
while (pCur)
{
PushStack(&s, pCur);
pCur = pCur->_Left;
}
BTNode* pTop = GetTopStack(&s);
if (pTop->_Right == NULL||pTop->_Right==pPrev)
{
printf("%c ", pTop->data);
pPrev = pTop;
PopStack(&s);
}
else
pCur = pTop->_Right;
}
DestroyStack(&s);
}