先序遍历
void preOrder(TNode* root)
{
if ( root != NULL)
{
Stack S;
S.push(root);
while (!S.empty())
{
TNode* node = S.pop();
Visit(node); // 先访问根节点,然后根节点就无需入栈了
if (node->right != NULL)
S.push(node->right); // 先push的是右节点,再是左节点
if (node->left != NULL)
S.push(node->left);
}
}
}
中序遍历:原理就是先将最左边的都压栈,直到最左边,然后出栈,出栈一个就访问它的右子树,这样就能保证右子树是在根节点访问之后再访问的,当然左子树是最先访问的
// 中序遍历伪代码:非递归版本,用栈实现
void InOrder(TNode* root)
{
Stack S;
while ( root != NULL || !S.empty() )
{
while( root != NULL ) // 左子树入栈
{
S.push(root);
root = root->left;
}
if ( !S.empty() )
{
root = S.pop();
Visit(root->data); // 访问根结点
root = root->right; // 通过下一次循环实现右子树遍历
}
}
}
后序遍历
注意到,后序遍历其实和前序遍历很相似,前序遍历顺序为 根节点->左子树->右子树,而后序遍历顺序为 左子树->右子树->根结点,因此,我们只要保证根节点最后访问即可,由于根节点是最先遍历到的结点,而我们想让他最后访问,那么这样的做法就是将该根结点压入另外一个栈,并且将右子树和左子树能够分别压入,然后,弹出该栈就能保证后序
可以用两个辅助栈,一个栈用来遍历,一个栈用来访问
代码如下
void postOrder(TNode *root)
{
if (root != NULL)
{
stack<TNode *> sTravel, sVisit;
sTravel.push(root);
while (!sTravel.empty())
{
TNode *p = sTravel.pop();
sVisit.push(p);
if (p->left != NULL) sVisit.push(p->left);
if (p->right != NULL) sVisit.push(p->right);
}
while (!sVisit.empty())
{
visit(sVisit.pop());
}
}
}