非递归实现二叉树的前序,中序以及后序遍历.
在非递归实现二叉树的前序,中序以及后序遍历时用到了栈这种数据结构.
一.非递归实现前序遍历.
我们知道二叉树的前序遍历是先访问根结点,然后访问左子树,最后再访问右子树.那仫如何非递归去前序遍历一颗树呢?
二 .非递归实现中序遍历.
非递归的中序遍历类似前序遍历只不过将访问当前结点的位置切换到访问左子树对应到代码中就是在入栈之后再访问当前结点.
void PrevOrderNoR()
{
stack<Node *> s;
Node *cur=_root;
while (cur || !s.empty())
{
while (cur) //一直向左遍历直到左为空时跳出
{
cout<<cur->_data<<" "; //访问根结点
s.push(cur);
cur=cur->_left;
}
//此时已经访问过当前结点且当前结点的左子树为空
Node *top=s.top();
s.pop();
//访问当前结点的右子树
cur=top->_right;
}
cout<<endl;
}
void InOrderNoR()
{
//类似非递归的先序遍历,不过要在访问过当前结点的左子树之后再访问根结点
stack<Node *> s;
Node *cur=_root;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur=cur->_left;
}
Node *top=s.top();
cout<<top->_data<<" ";
s.pop();
cur=top->_right;
}
cout<<endl;
}
三.非递归实现后序遍历.
如何使用非递归的方式遍历一颗树呢?我们知道后序遍历一棵树的原则是:先遍历左子树,再遍历右子树,最后再遍历根结点.而问题就出在根结点是在遍历了左子树和右子树之后才遍历的,如何在保证遍历了左右子树之后还能找到当前的根结点呢?
刚开始的想法类似前序遍历和中序遍历.一直遍历该树的左子树直到为空时不再压栈,只要停止压栈那仫栈顶结点的左子树已经访问过了而且一定为空,此时另当前元素为栈顶元素,如果判断当前结点的右子树为空或者右子树已经访问过了直接访问当前结点,如果右子树不为空或者右子树未被访问过则访问右子树.在实现中用到了一个prev指针过来记录当前结点的前一个结点.
void PostOrderNoR()
{
stack<Node *> s;
Node *cur=_root;
Node *prev=NULL;
while (cur || !s.empty())
{
while (cur)