非递归遍历是借助循环和栈来实现
先定义关于栈的一些操作:initStack(S):初始化栈S isEmpty(S):判断栈S是否为空 visit(p):访问结点p push(S,p):将结点p压入栈S中 pop(S,p):将栈顶结点从栈S中弹出并赋值给结点p getTop(S,p)访问栈顶结点并赋值给结点p
写代码时根据结点的访问顺序进行思考。先序遍历的访问顺序是根左右,具体的做法是:访问入栈->向左->出栈向右。中序遍历的访问顺序是左根右,具体的做法是:入栈向左->出栈访问->向右。后序遍历要注意辨别栈顶元素的右分支是否访问过,后序遍历的访问顺序是左右根,具体的做法是:入栈向左->栈顶判空判重向右入栈向左->出栈访问置空。
结束循环的条件有两个:p结点为空并且栈S为空(说明所有结点都已经访问过)。
//先序遍历
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;
}
}
}
//顺口溜:访问入栈(根)向左(左)出栈向右(右)
//中序遍历
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 PostOrder(BiTree T){
initStack(S);
BiTree p=T,r;
while(p||!isEmpty(S)){
if(p){
push(S,p);
p=p->lchild;
}else{
getTop(S,p);
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
push(S,p);
p=p->lchild;
}else{
pop(S,p);
visit(p);
r=p;
p=NULL;
}
}
}
}
//顺口溜: 入栈向左(左)栈顶判空判重向右入栈向左(右)出栈访问置空(根)
,