只是刚好牵涉到树的遍历的非递归,顺便三种都写一下。
参考:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
1.前序遍历
通过栈的方式,先访问根节点并入栈,在访问它的左子树,直到无左子树,此时不断提取栈顶访问其右子树即可。
void preOrder2(BinTree *root) //非递归前序遍历
{
stack<BinTree*> s;
BinTree *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
cout<<p->data<<" ";
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rchild;
}
}
}
2.中序遍历
与前序遍历类似,只不过将对根节点的访问放到了取栈顶时先访问根节点再访问右子树。
void inOrder2(BinTree *root) //非递归中序遍历
{
stack<BinTree*> s;
BinTree *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
cout<<p->data<<" ";
s.pop();
p=p->rchild;
}
}
}
3.后序遍历
后序遍历的非递归是最困难的。首先要用一个pre记录上一个访问的节点,然后将当前节点入栈,如果当前结点无左右子树或均被访问过,则可访问。否则将其右子树和左子树依次入栈。
void postOrder3(BinTree *root) //非递归后序遍历
{
stack<BinTree*> s;
BinTree *cur; //当前结点
BinTree *pre=NULL; //前一次访问的结点
s.push(root);
while(!s.empty())
{
cur=s.top();
if((cur->lchild==NULL&&cur->rchild==NULL)||
(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
{
cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();
pre=cur;
}
else
{
if(cur->rchild!=NULL)
s.push(cur->rchild);
if(cur->lchild!=NULL)
s.push(cur->lchild);
}
}
}
原理不难,但要熟练掌握还是要花点功夫的。