在二叉树中查找值为x的结点,打印值为x的结点的所有祖先,假设值为x的结点不多于一个。
采用非递归后序遍历算法,最后访问根节点,访问到值为x的结点时,栈中所有元素为该结点的祖先,从栈底到栈顶结点再加上当前访问的结点,刚好构成从根节点到当前访问结点的一条路径。在很多算法设计中都可以利用这一思路来求解,如求根到某结点的路径、求两个结点的最近公共祖先等。
栈的基本操作以严蔚敏编写的教材为准。
void PostOrder(BiTree T, int x)
{
InitStack(S); //初始化栈
BiTree p = T; //p为遍历指针
BiTree r = NULL; //r为辅组指针,指向最近访问过的结点。也可以在结点中增加一个标志域tag,记录是否已被访问
while(p || !StackEmpty(S)) //栈不空或p不空时循环
{
if(p) //一路向左
{
push(S, p);
p = p->lchild; //左孩子不空,一直向左走
}
else //向右
{
GetTop(S, p); //读栈顶结点(非出栈)
if(p->data == x) //如果栈顶结点的值等于x
{
while(!StackEmpty(S)) //则将栈中所有元素依次出栈打印
{
pop(S, p);
visit(p); //访问该结点
}
return 0; //执行完毕返回
}
if(p->rchild && p->rchild != r) //若右子树存在,且未被访问过
{
p = p->rchild; //转向右
push(S, p);
p = p->lchild; //再走到最左
}
else //否则,弹出结点
{
pop(S, p);
r = p; //记录最近访问过的结点
p = NULL; //结点访问完毕后,重置p指针,不然该结点又会重新入栈
}
}
}
}