/*
名称:输出二叉树中x的祖先结点,(二叉树中最多只有一个x)
说明:如果只是简单的找到指定结点的父节点有很多中方法,包括一直保存其父节点(也就是一直访问当前的子结点),使用递归,使用队列(层次遍历的思想)。但是在这里是需要找到x的所有的祖先节点,就稍微复杂一点了。在这里需要了解,对于二叉树的后序遍历(无论是递归还是非递归)来说,其对应的栈中一直保存着根节点到当前结点的一条路径。可以利用这个特点,来找寻指定节点的父节点。
在这里,本人使用的是递归算法。需要自己从栈中(这里的栈指的是函数,而非递归中的栈指得就是对应的结点)找到其祖先结点。那么就涉及到一个问题,你怎么知道当前结点的子孙结点中有没有x,利用函数的返回值最多只能返回一层,那么如何把信息返回给其祖先结点的。这里用的是引用flag,当在子结点查询到指定x时,就变更flag,将信息传递给其祖先结点。(当然,这里应该也可以用全局变量)。
总结:对于函数间的信息传递有三种方式:
(1)、主函数向被调用函数传参(普通参数:指针或引用类型)
(2)、被调用参数向主函数返回值
(3)、使用全局变量
对于递归函数间的调用关系来说,上层调用函数和下层被调用函数之间也可以用上述的三种方式传递信息。
由于递归在二叉树中用的较多,在此以二叉树为例讲解其一般的用法。
其中对于全局变量来说,它一般用于整个树。即,它的信息对于整个树是公用的。任何结点都可以改变其值来传递给其他所有结点。(这里说的结点改变其值指的是对应的调用递归函数层次)。比如说在算结点个数、输出第k个结点的值等等。
对于被调用函数向主函数返回值,在二叉树中就是一般子结点向父节点(被调用函数向调用函数)返回信息。比如说是从左子树返回还是从右子树返回等。
对于第(1)种情况,引用较多的是传递引用或指针类型。这样,既可以父结点向子结点传递参数,也可以用同一个变量,子结点向父节点返回一些信息。一般上面二中能实现的,传递引用参数都能实现,不过每次都要传递对应参数而已。
*/
int root ; //用来存放根结点的值
//后序递归输出二叉树中x的祖先结点(flag为标志位,初始值为0)
void FindPar_x(BiTree T,int x,int &flag)
{
if(1 == flag ||T == NULL)
return ;
else
{
FindPar_x(T->lchild,x,flag);
FindPar_x(T->rchild,x,flag);
if(T->data == x) //如果当前结点是x,则更换标志位
flag = 1;
if(flag == 1 && T->data != x)
{
cout<<T->data<<" ";
if(T->data == root) //如果输出到根结点,则再次更换标志位,否则可能会输出根节点右子树的元素(如果x在左子树的情况下)
flag = 0;
}
}
}