二叉搜索树的实现(递归方式)

这篇具有很好参考价值的文章主要介绍了二叉搜索树的实现(递归方式)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

实现思路

插入操作

删除操作

完整代码

测试案例

总结


二叉搜索树(Binary Search Tree,BST)是一种常用的数据结构,它具有以下特点:

  • 左子树上所有节点的值均小于它的根节点的值
  • 右子树上所有节点的值均大于它的根节点的值
  • 左右子树也分别为二叉搜索树

在实际应用中,BST被广泛使用,例如在数据库中的索引、哈希表等。

本文将介绍如何使用递归的方式实现BST,并提供完整代码和测试案例。

实现思路

BST的基本操作包括查找、插入和删除。这里我们只讲解递归方式实现BST的插入和删除操作。

插入操作

插入操作可以分为两种方式:

  • 版本一:传入父节点,通过比较key值大小,递归向下寻找插入位置。
  • 版本二:使用引用,第一步传参时,root是_root的别名;递归过程中,root是父节点指向它的指针的别名,修改root就是修改了父节点的连接。

版本二的实现方式更加简洁,因此我们选择使用版本二来实现插入操作。

删除操作

删除操作也可以分为两种方式:

  • 版本一:传入父节点,通过比较key值大小,递归向下寻找删除节点。
  • 版本二:使用引用,第一步传参时,root是_root的别名;递归过程中,root是父节点_left或·_right的别名,修改root就是修改了父节点的连接。

版本二同样更加简洁,因此我们选择使用版本二来实现删除操作。需要注意的是,当删除节点有两个子节点时,需要先找到其左子树中最大的节点右子树中最小的节点,将其值替换到要删除的节点上,再删除左子树中最大的节点右子树中最小的节点。

无论是查找、插入、删除,如果使用递归,都需要传参根节点,通过根节点来递归处理子问题,但是在类的实现中,成员变量根节点_root是私有变量,在类外无法访问,针对这种问题,C++常见的处理方式就是套用一层接口函数,定义对应功能的私有函数提供给接口函数调用;用户直接调用接口函数,和之前没有区别,接口函数内再调用对应功能的私有函数,私有函数只在类中使用,自然就可以调用BST的私有成员_root。

完整代码

#include<iostream>
using namespace std;

template <class K>
class BSTreeNode
{
public:
    BSTreeNode<K>* _left;
    BSTreeNode<K>* _right;
    K _key;

    BSTreeNode(const K& key)
        :_left(nullptr)
        , _right(nullptr)
        , _key(key)
    { }
};

template<class K>
class BSTree
{
    typedef BSTreeNode<K> Node;
public:
    bool Find(const K& key)
    {
        return _Find(_root, key);
    }

    bool Insert(const K& key)
    {
        return _Insert2(_root, key);
    }

    void midOrder()
    {
        _midOrder(_root);
    }

    bool Erase(const K& key)
    {
        return _Erase(_root, key);
    }
private:
    Node* _root = nullptr;

    bool _Find(Node* root, const K& key)
    {
        if (root == nullptr)
            return false;

        if (key < root->_key)
        {
            return _Find(root->_left, key);
        }
        else if (key > root->_key)
        {
            return _Find(root->_right, key);
        }
        else
        {
            return true;
        }
    }

    void _midOrder(Node* root)
    {
        if (root == nullptr)
            return;

        _midOrder(root->_left);
        cout << root->_key << " ";
        _midOrder(root->_right);
    }

    bool _Insert2(Node*& root, const K& key)
    {
        if (root == nullptr)
        {
            root = new Node(key);
            return true;
        }

        if (key < root->_key)
            return _Insert2(root->_left, key);
        else if (key > root->_key)
            return _Insert2(root->_right, key);
        else
            return false;
    }

    bool _Erase(Node*& root, const K& key)
    {
        if (root == nullptr)
            return false;

        if (key < root->_key)
            return _Erase(root->_left, key);
        else if (key > root->_key)
            return _Erase(root->_right, key);
        else
        {
            if (root->_left == nullptr)
            {
                Node* del = root;
                root = root->_right;
                delete del;
            }
            else if (root->_right == nullptr)
            {
                Node* del = root;
                root = root->_left;
                delete del;
            }
            else
            {
                //要删除的节点有两个子节点,替换法
				//先找到一个合适的替换节点,然后把值替换
				//合适的替换节点绝对是上面的几种情况:只有左子树、只有右子树、没有子节点
				Node* subRight = root->_left;
				while (subRight->_right)
				{
					subRight = subRight->_right;
				}
				swap(root->_key, subRight->_key);

				//交换值后,目前虽然整棵树不是搜索二叉树,但是root的左右子树都还是BST,递归去删除即可
				return _Erase(root->_left, key);
            }
        }
        return true;
    }
};

int main()
{
    int a[] = { 8,3,1,6,4,7,14,13 };
    BSTree<int> bst;
    for (int x : a)
    {
        bst.Insert(x);
    }
    bst.midOrder();

    //测试:遍历删除
    for (int x : a)
    {
        bst.midOrder();
        cout << endl;
        bst.Erase(x);
        bst.midOrder();
        cout << endl;
        cout << endl;
    }

    cout << "全部删除成功" << endl;
    system("pause");
    return 0;
}

测试案例

int a[] = { 8,3,1,6,4,7,14,13 };
BSTree<int> bst;
for (int x : a)
{
    bst.Insert(x);
}
bst.midOrder();

//测试:遍历删除
for (int x : a)
{
    bst.midOrder();
    cout << endl;
    bst.Erase(x);
    bst.midOrder();
    cout << endl;
    cout << endl;
}

cout << "全部删除成功" << endl;

 构建的二叉树如下:

二叉搜索树的实现(递归方式),数据结构与算法,C/C++,c++,算法,开发语言,数据结构

运行结果如下:

1 3 4 6 7 8 13 14 
1 3 4 6 7 8 13 14 
1 3 4 6 7 8 13 14 

1 3 4 6 7 13 14 
1 3 4 6 7 13 14 
1 3 4 6 7 13 14 

1 3 4 6 13 14 
1 3 4 6 13 14 
1 3 4 6 13 14 

1 3 4 6 13 
1 3 4 6 13 
1 3 4 6 13 

1 3 4 6 
1 3 4 6 
1 3 4 6 

1 3 4 
1 3 4 
1 3 4 

1 3 
1 3 
1 3 

1 
1 
1 

全部删除成功

总结

本文介绍了使用递归的方式实现BST的插入和删除操作,并提供了完整代码和测试案例。递归虽然简洁,但需要注意递归边界条件、参数传递方式等问题。在实际应用中,也可以使用迭代的方式实现BST的基本操作。文章来源地址https://www.toymoban.com/news/detail-719928.html

到了这里,关于二叉搜索树的实现(递归方式)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 数据结构:二叉树的基本操作(用递归实现)

    数据结构:二叉树的基本操作(用递归实现)

             本文将通过完成以下内容来展示二叉树的基本操作,代码解释标注全面而且清晰,代码书写也十分规范,适合初学者进行学习,本篇文章算是本人的一些学习记录分享,希望对有需要的小伙伴提供一些帮助~ 本文的内容为: 用递归的方法实现以下算法: 1.以二叉

    2024年02月06日
    浏览(8)
  • 【数据结构】二叉搜索树——二叉搜索树的概念和介绍、二叉搜索树的简单实现、二叉搜索树的增删查改

    【数据结构】二叉搜索树——二叉搜索树的概念和介绍、二叉搜索树的简单实现、二叉搜索树的增删查改

      二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:   (1)若它的左子树不为空,则左子树上所有节点的值都小于根节点的值   (2)若它的右子树不为空,则右子树上所有节点的值都大于根节点的值   (3)它的左右子树也分别为二叉

    2024年02月09日
    浏览(12)
  • 数据结构:二叉搜索树(非递归实现)

    数据结构:二叉搜索树(非递归实现)

    目录 1、二叉搜索树 2、二叉搜索树的相关操作。 1、查找 2、插入 3、删除 3、代码实现(非递归) 二叉搜索树(Binary Search Tree,简称BST)是一种特殊的二叉树,其中每个节点的值大于其左子树中所有节点的值,小于其右子树中所有节点的值。这种特性使得二叉搜索树具有快速

    2024年03月08日
    浏览(10)
  • 【数据结构】 二叉搜索树的实现

    【数据结构】 二叉搜索树的实现

    二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 比如以下就为一个人二叉搜

    2024年02月09日
    浏览(11)
  • 【数据结构】二叉搜索树BST的实现(递归)

    【数据结构】二叉搜索树BST的实现(递归)

    目录 1.概念 2.图解: 3.元素插入操作 1.思路分析: 2.代码展示: 4.元素查找操作 1.前提根节点不为空 2.代码展示: 5.查找BST中的最大最小值 代码展示: 6.删除BST中的最大最小值 代码展示: 7.删除BST中的任意元素 代码展示:   二叉搜索树又称二叉排序树,它或者是一棵空树,

    2023年04月09日
    浏览(8)
  • 数据结构与算法学习:二叉树的后序遍历的递归与非递归实现,以及非递归实现中的流程控制的说明。

    数据结构与算法学习:二叉树的后序遍历的递归与非递归实现,以及非递归实现中的流程控制的说明。

    需求二叉树: 采用二叉树后序遍历非递归算法。设置一个指针p初始指向树根,p先入栈,而后使得p指向它的左孩子p-firstchild,重复操作,使得每个左孩子都依次入栈,同时初始化一个Treenode*类型的指针 pre,这个指针是后序前驱,这个后序前驱用以区分为已访问过的结点和未

    2023年04月22日
    浏览(10)
  • 【算法与数据结构】二叉树的三种遍历代码实现(上)—— 用递归序知识点讲解

    【算法与数据结构】二叉树的三种遍历代码实现(上)—— 用递归序知识点讲解

      本篇博客 (上篇) 先带大家学习 递归方式 进行三种遍历, 而在后续的 (下篇) 中将为大家详细讲解非递归的三种遍历方式。 目录 1、二叉树 2、二叉树的递归遍历 2.1、先序遍历 2.2、中序遍历 2.3、后序遍历  二叉树(Binary tree)是树形结构的一个重要类型。许多实际问

    2024年02月08日
    浏览(15)
  • 数据结构之进阶二叉树(二叉搜索树和AVL树、红黑树的实现)超详细解析,附实操图和搜索二叉树的实现过程图

    数据结构之进阶二叉树(二叉搜索树和AVL树、红黑树的实现)超详细解析,附实操图和搜索二叉树的实现过程图

    绪论​ “生命有如铁砧,愈被敲打,愈能发出火花。——伽利略”;本章主要是数据结构 二叉树的进阶知识,若之前没学过二叉树建议看看这篇文章一篇掌握二叉树,本章的知识从浅到深的 对搜索二叉树的使用进行了介绍和对其底层逻辑的实现进行了讲解 ,希望能对你有所

    2024年02月04日
    浏览(13)
  • Java 数据结构篇-实现二叉搜索树的核心方法

    Java 数据结构篇-实现二叉搜索树的核心方法

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍   文章目录         1.0 二叉搜索树的概述         2.0 二叉搜索树的成员变量及其构造方法         3.0 实现二叉树的核心接口         3.1 实现二叉搜索树 - 获取值 get(int key)         3.2 实现二叉搜索树

    2024年02月04日
    浏览(12)
  • 【数据结构】二叉树的遍历递归算法详解

    【数据结构】二叉树的遍历递归算法详解

    我们来写一个函数 BuyNode(x)函数 用于创建二叉树结点。 用动态开辟函数 malloc 函数进行动态开辟,并强制转换为 BTNode 型,用变量 node 来去管理开辟的空间。 我们初始化结点,其 val 即为传入的参数x,左右指针 left 和 right 都设为NULL。 我们在主函数中创建上面这样一颗二叉树

    2024年01月20日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包