二叉树的前驱和后继(内附视频讲解,各种语言的代码实现)

本小妞迷上赌 提交于 2020-02-11 06:44:52

二叉树的前驱和后继(内附视频讲解,各种语言代码实现)

视频讲解:

这是博主自己的视频,谢谢大家。
b站链接:https://www.bilibili.com/video/av87266752

原理

前驱节点:对一颗二叉树进行中序遍历,按照其遍历后的顺序,当前节点的前一个节点为该节点的前驱节点。
后继节点:对一颗二叉树进行中序遍历,按照其遍历后的顺序,当前节点的后一个节点为该节点的后继节点。

以9为例子:
在这里插入图片描述
如果对遍历顺序不太熟悉的兄弟,可以看一下博主的另外一个文章《二叉树的遍历方式(内附视频讲解,各种语言的中序遍历代码实现)》,原文链接:https://blog.csdn.net/weixin_44421437/article/details/104171113

后继节点

首先我们来看一下伪代码:
在这里插入图片描述
解释一下TREE-MINIUM(x),二叉树的性质(左子节点小于右子节点)决定了二叉树的最小值在左子树的最下面的最左边。
也就是这样:
在这里插入图片描述
为什么说,当右子节点不为空的时候,它的后继为由子树的最小值? 这是由中序遍历的顺序决定的,左,自己,右,父子节点。
在这里插入图片描述
那么好,接下来以元素4为例子进行讲解。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

前驱

前驱和后继差不多不重复讲解,贴出伪代码完事。
在这里插入图片描述

具体实现

C++语言的前驱和后继代码实现,转载至csdn博主王道鹰击长空的《二叉树的前驱和后继》博文,侵删:
相关链接:https://blog.csdn.net/liuchaoswu/article/details/45456707

//定义数据结构
template<typename T> struct BNode
{
    T m_data;
    BNode<T>* rchild;
    BNode<T>* lchild;
    BNode<T>* parent;
    int ltag;
    int rtag;
    BNode(T data=0):m_data(data),rchild(NULL),lchild(NULL),parent(NULL),ltag(0),rtag(0){}
};
template<typename T> struct BTree
{
    BNode<T>* m_root;
    BNode<T>* index;
    BNode<T>* pre;
    T m_data;
    BTree(BNode<T>* root=NULL,T data=0):m_root(root),m_data(data),pre(NULL){}
}




T get_pre(BNode<T>* root)/*查找一个中序遍历二叉树节点的前驱节点*/
{
    if(root==NULL)
    {
        return 0;
    }
    if(root->lchild)
    {
        BNode<T>* start=root->lchild;
        while(start->rchild)
        {
            start=start->rchild;
        }
        return start->m_data;
    }
    else if(root->parent)
    {
        BNode<T>* father=root->parent;
        BNode<T>* current=root;
        while(father&&father->lchild==current)
        {
            current=father;
            father=father->parent;
        }
        if(father)
        {
            return father->m_data;
        }
        return 0;
    }
}


T get_suc(BNode<T>* root)/*查找一个中序遍历二叉树节点的后继节点*/
{
    if(root==NULL)
    {
        return 0;
    }
    if(root->rchild)
    {
        BNode<T>* right=root->rchild;
        while(right->lchild)
        {
            right=right->lchild;
        }
        return right->m_data;
    }
    else if(root->parent)
    {
        BNode<T>* father=root->parent;
        BNode<T>* current=root;
        while(father&&father->rchild==current)
        {
            current=father;
            father=father->parent;
        }
        if(father)
        {
            return father->m_data;
        }
        return 0;
    }
}

Java语言的前驱和后继代码实现,转载至csdn博主canmengmeng的《二叉树的后继节点Java》博文,侵删:
相关链接:https://blog.csdn.net/canmengmeng/article/details/81348081

public static Node getSuccessorNode(Node node) {
	if (node == null) {
		return node;
	}
	if (node.right != null) {
		return getLeftMost(node.right);
	} else {
		Node parent = node.parent;
		while (parent != null && parent.left != node) {
			node = parent;
			parent = node.parent;
		}
		return parent;
	}
}
 
public static Node getLeftMost(Node node) {
	if (node == null) {
		return node;
	}
	while (node.left != null) {
		node = node.left;
	}
	return node;
}

参考资料:
CSDN博主王道鹰击长空的《二叉树的前驱和后继》博文:https://blog.csdn.net/liuchaoswu/article/details/45456707
CSDN博主Xiyou_limeng的《线索二叉树中查找前驱和后继的问题》博文:https://blog.csdn.net/ldx19980108/article/details/78516382
CSDN博主canmengmeng的《二叉树的后继节点Java》博文:https://blog.csdn.net/canmengmeng/article/details/81348081
算法导论
数据结构与算法分析–c++语言描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!