算法思想:后序遍历非递归算法。当访问到x节点时,栈中所有元素都是祖先,依次出栈
后序遍历非递归:
1.从根节点开始非空则进栈,一直进行到最左叶节点(仍然进栈,其下一步为2);
2.若遇到空节点,退栈,访问,并用r指针标记最新访问节点。
void Ancestor(btree t,elemtype k){
initstack(s); //初始化栈
btnode *p=t,r=null; //r记录最新访问节点
while(p||!empty(s)){
if(p){ //走到最左边(未必是叶节点)
push(s,p);//进栈
p=p->lchild;
}
else{
gettop(s,p);//获取栈顶元素判断是否为叶节点,或者是否为从右子树返回
if(p->rchild&&p->rchild!=r){//右子树存在且不是从右子树返回
push(s,p->rchild);
p=p->rchild->lchild;//转到右子树的左孩子
}
else{//p为叶节点,或者从右子树返回根节点
pop(s,p);
-------------
if(p->data==k){ //找到k节点,输出栈内元素,并退出
outputstack(s);
return ;
}//除了这部分if(),其余都是后序遍历非递归算法
-------------
r=p; //记录最新访问(出栈)的节点
p=null; //p置为空,以防再次入栈
}//else
}//else
}//while
}
如果要查找x,y的共同祖先,则可以对比两个出栈序列,遇到相同的时候,其后面的都是共同祖先。