InitStack(S);//初始化栈
p=T;//取栈顶
while(P||!StackEmpty(S)){ //P存在或者栈非空
if(p) { //p非空,即左子树或者右子树存在
Push(S,p); //将左子树入栈
p=p->lchild; //取下一个左子树
}
else{
Pop(S,p); //出栈,相当于先序遍历了,因为左子树都TMD入栈了,现在反向输出
p=p->rchild; //弹出一个左子树,就同时取其右子树右子树,然后又跳到这个if的最开头那里,p存在的那个分支。接下来再取右子树的左子树
}
}
//其实,用递归也许你更能理解一些。但是,递归本质上也是压栈,只不过是程序压栈,还不如这个效率高
这个比较难回答,建议你画一棵树,对着算法一步一步画出堆栈。我们老师都是这样教我们的。
可以告诉你的是,在前面很多轮中,p一直往树左边走,最后走到最左边的叶子,这就是先序遍历的第一个节点拉~~。然后才有POP的操作。建议你在网上搜搜博客之类的,讲的比较详细。先序遍历的非递归算法还有其他版本,这个版本是最好记的~~~不过理解就是另一回事了。很多算法要严格用数学语言描述和证明可不容易阿~
如果while if 你也不懂的话,那么对于入栈出栈也必然不懂了,所以,没办法讲清楚,找本数据结构的书看看吧。