左神课堂之寻找二叉树的前驱节点和后继节点

前驱节点:二叉树中序遍历完成后和这个节点相邻的前面的节点为该节点的前驱节点

后继节点:二叉树中序遍历完成后和这个节点相邻的后面的节点为该节点的后继节点


中序遍历顺序:8->4->9->2->10->5->1->6->3->7

4号节点的前驱节点为8号节点,后继节点为9号节点。

正常的二叉树的数据结构:

struct node
{
    node left;//左节点
    node right;//右节点
    int value;

};

本题中二叉树的数据结构:

struct node
{
    node left;//左节点
    node right;//右节点
    node parent;//该节点的父亲节点
    int value;

};

比普通的二叉树结构多了一个指向该节点父亲节点的指针,我们规定:头节点指向其父亲节点的指针为空或者是头节点本身

前驱节点

1:如果当前节点的左子树不为空,那么该点的前驱节点为该点左子树中最右的节点     

假设求上图中1节点的前驱节点,1节点的左子树不为空,那么1节点的前驱节点为左子树中最右的节点--5节点

2:如果当前节点的左子树为空,那么该点的前驱节点为从该点往上延伸,如果延伸到的点为其父亲节点的右孩子,那么这个父亲节点就是该点的前驱节点

假设求上图中10号节点的前驱节点,10号节点的左子树为空,10号节点不是其父亲节点的右孩子,往上延伸,看5号节点,5号节点是其父亲的右孩子,那么,2号节点就是10号节点的前驱节点

注意,这里有一种特殊情况,看上图的8号节点,8号节点的左子树为空,8号节点不是其父亲的左子树,往上延伸,看4号节点,4号节点不是其父亲节点的左子树,往上延伸,看1号节点,1号节点没有父亲节点了,这种特殊情况在codiing中已经做了处理,等会看代码就懂了。

代码如下:

struct node
{
    node left;//左孩子
    node right;//右孩子
    node parent;//父亲节点
    int value;
};
node getfristornode(node heap)//heap代表当前要找前驱节点的节点
{
    if(heap==null)//如果当前节点为空,返回空
        return heap;
    if(heap.left!=null)//如果当前节点左子树不为空,那么该节点的后继节点为左子树中最右的节点
        return getrightmost(heap.left);//找到左子数树中最右的节点,并返回
    else                               //如果程序到达这里,说明当前节点的左子数为空
    {
        node parent=heap.parent;
        while (parent!=null&&heap!=parent.right)//第一个条件就是判断那种特殊情况的,一直延伸到当前节点没有父亲节点时,那么parent为空,这个条件不满足,函数返回空
        {                                       //第二个条件是判断当前节点是否为该父亲节点的右孩子,如果不是,继续执行下面的代码,如果是,说明这个父亲节点就是heap节点的前驱节点
            heap=parent;
            parent=heap.parent;
        }
        return parent;
    }
}
getrightmost(node heap)//这个函数是求左子树中最右的节点的函数
{
    while (heap!=null)
        heap=heap.right;
    return heap.parent;

}

后继节点

和求前驱节点差不多,直接上代码:

struct node
{
    node left;//左孩子
    node right;//右孩子
    node parent;//父亲节点
    int value;
};
node getsuccessornode(node heap)//heap代表当前要找后继节点的节点
{
    if(heap==null)//如果当前节点为空,返回空
        return node;
    if(heap.right!=null)//如果当前节点右子树不为空,那么该节点的后继节点为右子树中最左的节点
        return getleftmost(haep.right);//找到右子数树中最左的节点,并返回
    else //如果程序到达这里,说明当前节点的右子数为空
    {
        node parent=heap.parent;
        while (parent!=null&&haep!=parent.left)//第一个条件就是判断那种特殊情况的,一直延伸到当前节点没有父亲节点时,那么parent为空,这个条件不满足,函数返回空
        {                                      //第二个条件是判断当前节点是否为该父亲节点的左孩子,如果不是,继续执行下面的代码,如果是,说明这个父亲节点就是heap节点的后继节点
            haep=parent;
            parent=haep.parent;
        }
        return parent;
    }
}
node getleftmost(node heap)//这个函数是求右子树中最左的节点的函数
{
    while (heap!=null)
        heap=heap.left;
    return heap.parent;
}

猜你喜欢

转载自blog.csdn.net/qq_40938077/article/details/80463299