分析: 两种思路,递归和非递归。
思路: 考虑递归,当前结点值不等于 x 时,递归其左右子树,如果两者有一个返回值为 true,则说明当前结点为 x 的祖先结点,直接打印。
bool AncestorX(BiTree T,ElemType x){
if(T == NULL)
return false;
if(T->data == x)
return true;
if(AncestorX(T->lchild,x) || AncestorX(T->rchild,x))
printf(T->data);
}
思路: 非递归,因为在遇到 x 的时候需要将其所有祖先打印,而当访问到 x 且能保留x 的祖先的方法,只有使用后序非递归遍历()。
void AncestorX2(BiTree T,ElemType x){
InitStack(S);
BiTNode *p = T;
BiTNode *r = NULL;
while(p || !IsEmpty(S)){
if(p){
push(S,p);
p = p->lchild;
}
else{
GetTop(S,p);
if(p->data == x){
pop(S,p); //先把等于 x 的结点弹出
while(!IsEmpty(S)){
pop(S,p);
printf(p->data);
}
return;
}
if(p->rchild && p->rchild != r)
p = p->rchild;
else{
pop(S,p);
r = p; //记录右结点已访问
p = NULL; //防止再次把 p 结点压入栈
}
}
}
}