考研中树的递归转非递归中最难的是后序遍历,它需要通过标记的处理来确定已经访问过的结点,并且访问之后p指针置空的操作能够有效的避免向左继续访问,转而直接读取刚刚访问过的结点的父节点
1 Void PostOrder(BiTree T){
2 InitStack(S);
3 BiTree p=T,r=NULL;
4 while(p||!IsEmpty(S)){
5 if(p){ //如果p不为空
6 push(S,p); //一路沿左走压入栈
7 p=p->lchild;
8 }
9 else{ //如果为空则开始处理右子树
10 GetTop(S,p); //把指针指向栈顶元素(空节点的父节点)
11 if(p->rchild&&p->rchild!=r){
12 //若此节点的右孩子没有被访问过且不为空
13 p=p->rchild; //把指针指向右结点
14 }
15 else{ //若右孩子不满足被访问条件,则说明此节点为根的子树已经访问完毕,把它弹出栈并标记
16 pop(S,p);
17 visit(p);
18 r=p;
19 p=NULL; //把p置空是为了不再访问此节点的左右子树了,转而通过下一轮的GetTop函数指向栈顶结点,即该节点的父节点
20 }
21 }
22 }
23 }
2022-10-10