使用栈辅助实现二叉树的非递归前序、中序和后序遍历
前序遍历:
遍历顺序:根->左子树->右子树
分析:先访问根,右子树入栈,然后访问左子树
void PreOrderNoRecursion(BinaryNode* bt){
stack<BinaryNode*> s;
BinaryNode* p = bt;
while (p!=NULL || !s.empty()){
if (p==NULL){
p = s.top(); s.pop();
}
cout<<p->data<<" ";
if (p->rchild != NULL)
s.push(p->rchild);
p = p->lchild;
}
}
中序遍历:
遍历顺序:左子树->根->右子树
分析:将根入栈,先访问左子树,根出栈之后,访问根,然后访问右子树
void InOrderNoRecursion(BinaryNode* bt){
stack<BinaryNode*> s;
BinaryNode* p = bt;
while(p!=NULL || !s.empty()){
if (p!=NULL){
s.push(p);
p = p->lchild;
} else {
p = s.top(); s.pop();
cout<<p->data<<" ";
p = p->rchild;
}
}
}
后序遍历:
遍历顺序:左子树->根->右子树
分析:先将根入栈,访问左子树,然后根出栈,如果没有访问右子树,则将根入栈先访问右子树,否则访问根,然后向上继续。此处使用一个pre指针判断是否已访问右子树,根据后序遍历的顺序,一个节点的前驱节点是其右子树的根节点,如果pre指向其右子树根节点,则其右子树已访问,否则未访问。
void PostOrderNoRecursion(BinaryNode* bt){
stack<BinaryNode*> s;
BinaryNode* p = bt;
BinaryNode* pre = NULL;
while (p!=NULL || !s.empty()){
if (p!=NULL){
s.push(p);
p = p->lchild;
} else {
p = s.top();
if (p->rchild!=NULL && p->rchild!=pre){//右子树不为空并且右子树未访问
p = p->rchild;
} else {
s.pop();
cout<<p->data<<" ";
pre = p;
p = NULL; //将p置为空,以便下次从堆栈中弹出下一个节点
}
}
}
}