中序遍历的访问过程:
1.沿着根的左孩子,依次入栈,直到左孩子为空,说明已经找到可以输出的节点。
2.栈顶元素出栈并访问,若其右孩子为空,继续执行2。
3.若右孩子不空,将右子树转执行1。
void InOrder(BiTree T){
InitStack(S); BiTree p=T;
while(p||!IsEmpty(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
visit(p);
p=p->rchild;
}
}
}
先序遍历:
void PreOrder(BiTree T){
InitStack(S); BiTree p=T;
while(p||!IsEmpty(S)){
if(p){
visit(p);
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
}
后序遍历:
1.沿着根的左孩子依次入栈,直到左孩子为空。
2.读栈顶元素(不弹出),若其右孩子不空且未被访问过,将右子树转执行1;否则栈顶元素出栈并访问。
在2中必须分清返回时是从左子树返回还是从右子树返回的,因此设定一个辅助指针r,指向最近访问过的节点。
void PostOrder(BiTree T){
InitStack(S);
p=T;
r=NULL;
while(p||!IsEmpty(s)){
if(p){ //走到最左边
push(S,p);
p=p->lchild;
}
else{
GetTop(S,p); //读栈顶节点(非出栈)
if(p->rchild&&p->rchild!=r){ //若右子树存在,且未被访问过
p=p->rchild; //转向右
push(S,p); //压入栈
p=p->lchild; //在走到最左
}
else{ //否则弹出节点并访问
pop(S,p);
visit(p->data);
r=p; //记录最近访问的结点
p=NULL; //每次出栈访问完一个节点就相当于遍历完以该节点为根的子树,需将p置为NULL。
}
}
}
}