在递归调用过程用,每次调用函数都要把当前的局部变量压栈。所有递归函数,使用栈都可以写成非递归调用。
上篇“二叉树的递归遍历”使用栈即可写成非递归遍历。
//先序遍历
void BinTree::preoeder(Node *r,void (*visit)(int data))
{
stack<Node*> S;
Node *current=r;
while(current!=NULL||S.empty()==false)
{
while(current!=NULL)
{
visit(current->data);
S.push(current);
current=current->left;
}
current=S.top();
S.pop();
current=current->right;
}
}
//中序遍历
void BinTree::inorder(Node *r,void (*visit)(int data))
{
stack<Node*> S;
Node *current=r;
while(current!=NULL||S.empty()==false)
{
while(current!=NULL)
{
S.push(current);
current=current->left;
}
current=S.top();
S.pop();
visit(current->data);
current=current->right;
}
}
//后序遍历
void BinTree::postoeder(Node *r,void(*visit)(int data))
{
stack<Node*> S;
Node *current=r;
Node *last=NULL;//记录上次遍历的结点
while(current!=NULL||S.empty()==false)
{
while(current!=NULL)
{
S.push(current);
current=current->left;
}
current=S.top();
if(current->right==NULL||current->right==last)//无右孩子或右孩子已经访问过,那么可以访问此节点
{
visit(current->data);
last=current;
S.pop();
current=NULL;
}
else
current=current->right;
}
}
层次遍历要使用队列,按照层次一次入队出队来遍历。
//层次遍历
void BinTree::levelorder(Node *r,void (*visit)(int data))
{
queue<Node*> Q;
Q.push(r);
while(!Q.empty())
{
Node *current=Q.front();
Q.pop();
visit(current->data);
if(current->left!=NULL)
Q.push(current->left);
if(current->right)
Q.push(current->right);
}
}