- 非递归前序遍历:
void PreOrder(BiTree root)
{
stack<BiTree> bitreeStack;
while(root!=NULL || !bitreeStack.empty())
{
while(root!=NULL)
{
cout<<root->data<<endl;
bitreeStack.push(root);
root=root->lchild;
}
if(!bitreeStack.empty())
{
root=bitreeStack.top();
bitreeStack.pop();
root=root->rchild;
}
}
}
- 非递归中序遍历
void InOrder(BiTree root)
{
stack<BiTree> bitreeStack;
while(root!=NULL || !bitreeStack.empty())
{
while(root!=NULL)
{
bitreeStack.push(root);
root=root->lchild;
}
if(!bitreeStack.empty())
{
root=bitreeStack.top();
bitreeStack.pop();
cout<<root->data<<endl;
root=root->rchild;
}
}
}
- 非递归后序遍历:
转自:http://blog.csdn.net/jiqiren007/article/details/6461761
下面是后序遍历二叉树的非递归实现,与前序和中序的非递归略有不同,主要是要判断某个节点的右子树是否已经访问过,如果没有访问过,则访问该节点的右子树;如果访问过其右节点,则访问该节点。因此代码中利用了临时变量lastvisit来标记上次访问的节点。
void postorder_travese_norec(tree root, void(*visit)(node))
{
tree stack[32];
int top = 0;
tree p = root;
tree lastvisit = NULL; //用于标记上次访问的节点
for(; top<32; top++)
{
stack[top] = NULL;
}
top = 0;
while(p != NULL || top > 0)
{
while(p != NULL)
{
stack[top++] = p; //将所有左子树压入栈中
p = p->lchild;
}
p = stack[top - 1]; //注意这里,不是p = stack[—top],因为我们还不知道是否要访问p
if(p->rchild == NULL || lastvisit == p->rchild) //判断p的右子树是否访问过或者是否为空
{
visit(*p);//如果p的右子树为空或者已经访问过,则访问p
lastvisit = p;//标记上次访问的是节点p
top--; //这里p已经访问过,则将栈中的p弹出即可
p = NULL;
}
else
{
p = p->rchild; //如果p的右子树还没有访问过,那么访问其右子树
}
}
}
堆栈用STL的stack容器实现,面试时写下面这段代码:
void PostOrderTraverseByStack(BiTree root)
{
stack<BiTree>bitreeStack;
BiTree lastVisited = NULL;
while(root!=NULL||!bitreeStack.empty())
{
while(root!=NULL)
{
bitreeStack.push(root);
root=root->lchild;
}
root=bitreeStack.top();
if(root->rchild == NULL || lastVisited == root->rchild)
{
cout<<root->data<<endl;
lastVisited = root;
bitreeStack.pop();
root=NULL;
}
else
root=root->rchild;
}
return;
}