非递归实现中序遍历:
先附上代码:
//非递归实现中序遍历
void zhongXu(BiTree &T){
Stack St;//利用栈,其实递归函数本质就是用的栈
BiTree p = T;
initStack(St);//初始化栈
while(!isEmpty(St) || p){//这里必须是栈空并且p指向null了才退出
if(p){
push(St,p);
p = p->lchild;//一路向北
}
else{
pop(St,p);
visit(p);
p=p->rchild;//判断右孩子
}
}//endwhile
}
思路:
if(p){
push(St,p);
p = p->lchild;//一路向北
}
p不为空时,将p压入栈,在找到其左孩子,直到p指向了最左边最下面的叶子结点的左孩子(null),此时,栈内应该是这样的(右侧为栈顶)
a1,a2,a3 |
---|
因为p此时为null,接下来就会进入另外的代码
else{
pop(St,p);
visit(p);
p=p->rchild;//判断右孩子
}
你可以理解为p遇到了下限了就往回跑了,于是便将栈顶元素弹出,判断右孩子树的情况。
****注意:****为什么我们这里只判断右孩子就可以呢?因为左孩子早就被我们“一路向北”走完并且存在栈里了,这个时候你可以把已经进入栈的做分支当作主干,而里面每个节点都有对应的右孩子树,对这些右孩子树又是一样的过程(其实这里有递归的逻辑)
1.为什么使用在栈?
答:模仿递归函数的执行过程,需要依赖栈(后进先出)