【C++进阶学习】二叉搜索树(1)

简介: 【C++进阶学习】二叉搜索树(1)

零、前言


我们都知道二叉树只有附加上一些特性才具有实用的价值,而本章主要讲解二叉树进阶的内容-二叉搜索树


一、二叉搜索树概念及分析


  • 概念:



二叉搜索树(Binary Search Tree)又称二叉排序树,也称作二叉查找树它或者是一棵空树,或者是具有以下性质的二叉树:


若它的左子树不为空,则左子树上所有节点的值都小于根节点的值


若它的右子树不为空,则右子树上所有节点的值都大于根节点的值


它的左右子树也分别为二叉搜索树


示图:


性能:

二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,为O(log n)(理想状态下和完全二叉树形似)


注:对于极端状态下,查找、插入为O(n)(形似单链表)


示图:


二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如map,set等


二、二叉搜索树的详解及模拟


1、二叉搜索树的结构


  • 二叉搜索树结点结构:


template<class K>
struct BSTreeNode
{
    //记录左右子树
  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 Insert(const K& key);
  Node* Find(const K& key);
  bool Erase(const K& key);
  void InOrder();
private:
    void _InOrder(Node* root);
  Node* _root = nullptr;
};


注:由于二叉搜索树的特性,所以二叉搜索树不能修改key


2、二叉树搜索树的构造和析构


  • 实现代码:


BSTree()
    :_root(nullptr)
    {}
BSTree(const BSTree<K>& t)
{
    _root = _Copy(t._root);
}
BSTree<K>& operator=(BSTree<K> t)
{
    std::swap(_root, t._root);
    return *this;
}
~BSTree()
{
    _Destory(_root);
}
Node* _Copy(Node* root)
{
    //空结点构建
    if (root == nullptr)
        return nullptr;
    //构建当前结点
    Node* newnode = new Node(root->_key);
    //递归构建左右子树
    newnode->_left = _Copy(root->_left);
    newnode->_right = _Copy(root->_right);
    return newnode;
}
void _Destory(Node*& root)
{
    if (root == nullptr)
        return;
    //后序遍历释放结点
    _Destory(root->_left);
    _Destory(root->_right);
    //释放置空结点
    delete root;
    root = nullptr;
}


3、二叉搜索树的查找


  • 具体操作过程:


  1. 若走到空节点,则搜索失败,返回空指针
  2. 若key大于当前结点的数据域之值,则搜索右子树
  3. 若key小于当前结点的数据域之值,则搜索左子树
  4. 若key等于当前结点的数据域之值,则查找成功,返回当前结点地址


  • 示图:查找32


  • 迭代实现:


Node* Find(const K& key)
{
    Node* cur = _root;
    while (cur)
    {
        if (cur->_key > key)
        {
            cur = cur->_left;
        }
        else if (cur->_key < key)
        {
            cur = cur->_right;
        }
        else
        {
            return cur;
        }
    }
    return nullptr;
}


  • 递归实现:


Node* FindR(const K& key)
{
    return _FindR(_root,key);
}
Node* _FindR(Node* root, const K& key)
{
    if (root == nullptr)
        return nullptr;
    if (root->_key == key)
        return root;
    else if (root->_key > key)
        return _FindR(root->_left, key);
    else
        return _FindR(root->_right, key);
}


  • 注意:
  1. 实现子函数便于递归,并且保护私有成员
  2. 子函数一般建议设置为私有,避免接口暴露
相关文章
|
6天前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
37 16
|
24天前
|
算法 网络安全 区块链
2023/11/10学习记录-C/C++对称分组加密DES
本文介绍了对称分组加密的常见算法(如DES、3DES、AES和国密SM4)及其应用场景,包括文件和视频加密、比特币私钥加密、消息和配置项加密及SSL通信加密。文章还详细展示了如何使用异或实现一个简易的对称加密算法,并通过示例代码演示了DES算法在ECB和CBC模式下的加密和解密过程,以及如何封装DES实现CBC和ECB的PKCS7Padding分块填充。
45 4
2023/11/10学习记录-C/C++对称分组加密DES
|
5月前
|
算法 C语言 C++
C++语言学习指南:从新手到高手,一文带你领略系统编程的巅峰技艺!
【8月更文挑战第22天】C++由Bjarne Stroustrup于1985年创立,凭借卓越性能与灵活性,在系统编程、游戏开发等领域占据重要地位。它继承了C语言的高效性,并引入面向对象编程,使代码更模块化易管理。C++支持基本语法如变量声明与控制结构;通过`iostream`库实现输入输出;利用类与对象实现面向对象编程;提供模板增强代码复用性;具备异常处理机制确保程序健壮性;C++11引入现代化特性简化编程;标准模板库(STL)支持高效编程;多线程支持利用多核优势。虽然学习曲线陡峭,但掌握后可开启高性能编程大门。随着新标准如C++20的发展,C++持续演进,提供更多开发可能性。
95 0
|
2月前
|
存储 C++
【C++】二叉搜索树(BST)
二叉搜索树(Binary Search Tree, BST)是一种特殊的二叉树,其每个节点的左子树所有节点值小于该节点值,右子树所有节点值大于该节点值,且左右子树也均为二叉搜索树。BST支持高效的数据查找、插入和删除操作,时间复杂度通常为O(log n)。本文档详细介绍了BST的基本概念、存储结构及其实现,包括迭代和递归两种方式的查找、插入、删除等操作的具体代码示例。
51 3
|
3月前
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
|
3月前
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
34 1
|
6月前
|
存储 C++
【C++】二叉树进阶之二叉搜索树(下)
【C++】二叉树进阶之二叉搜索树(下)
38 4
|
6月前
|
Java 编译器 C++
【C++】二叉树进阶之二叉搜索树(上)
【C++】二叉树进阶之二叉搜索树(上)
40 3
|
6月前
|
存储 安全 编译器
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
|
2天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
32 18