C++进阶--搜索二叉树

简介: C++进阶--搜索二叉树

概念

搜索二叉树是一种特殊的二叉树,其具有以下特点:

1.对于每个结点,它的左子树中的所有节点的值都小于该节点的值,而右子树中的所有节点的值都大于该节点的值

2.左子树和右子树都是搜索二叉树

这个 特性使得搜索二叉树可以用于高效地进行查找、插入和删除操作。通过利用节点之间的大小关系,我们可以快速定位到目标值所在的位置,避免不必要的比较操作。

在数据结构专栏已经讲解过了二叉树了:

二叉树1

二叉树2

下面直接讲解对搜索二叉树的实现。

实现搜索二叉树

二叉树结点模板

默认构造

查找

插入

bool Insert(const K& key)
    {
      if (_root == nullptr)
      {
        _root = new Node(key);
        return true;
      }
      Node* parent = nullptr;
      Node* cur = _root;
      while (cur)
      {
        if (key > cur->_key)
        {
          parent = cur;
          cur = cur->_right;
        }
        else if (key < cur->_key)
        {
          parent = cur;
          cur = cur->_left;
        }
        else
        {
          return false;
        }
      }
      cur = new Node(key);
      if (key > parent->_key)
      {
        parent->_right = cur;
      }
      else
      {
        parent->_left = cur;
      }
      return true;
    }

删除

bool Erase(const K& key)
    {
      Node* parent = nullptr;
      Node* cur = _root;
      while (cur)
      {
        if (key > cur->_key)
        {
          parent = cur;
          cur = cur->_right;
        }
        else if (key < cur->_key)
        {
          parent = cur;
          cur = cur->_left;
        }
        else
        {
          if (cur->_left == nullptr)
          {
            if (cur == _root)
            {
              _root = cur->_right;
            }
            else
            {
              if (cur == parent->_right)
              {
                parent->_right = cur->_right;
              }
              else
              {
                parent->_left = cur->_right;
              }
            }
            delete cur;
            return true;
          }
          else if (cur->_right == nullptr)
          {
            if (cur == _root)
            {
              _root = cur->_left;
            }
            else
            {
              if (cur == parent->_left)
              {
                parent->_left = cur->_left;
              }
              else
              {
                parent->_right = cur->_left;
              }
            }
            delete cur;
            return true;
          }
          else
          {
            Node* rightMinParent = cur;
            Node* rightMin = cur->_right;
            while (rightMin->_left)
            {
              rightMinParent = rightMin;
              rightMin = rightMin->_left;
            }
            cur->_key = rightMin->_key;
            if (rightMin == rightMinParent->_left)
            {
              rightMinParent->_left = rightMin->_right;
            }
            else
            {
              rightMinParent->_right = rightMin->_right;
            }
            delete rightMin;
            return true;
          }
        }
      }
      return false;
    }

拷贝、赋值、析构

递归版本的增删查

删除:

bool _EraseR(Node*& root,const K& key)
    {
      if (root == nullptr)
        return false;
      if (root->_key < key)
        return _EraseR(root->_right, key);
      else if (root->_key > key)
        return _EraseR(root->_left, key);
      else
      {
        Node* del = root;
        if (root->_right == nullptr)
          root = root->_left;
        else if (root->_left == nullptr)
          root = root->_right;
        else
        {
          Node* rightMin = root->_right;
          while (rightMin->_left)
            rightMin = rightMin->_left;
          swap(root->_key, rightMin->_key);
          return _EraseR(root->_right, key);
        }
        delete del;
        return true;
      }
    }

实现源码

#pragma once
namespace fnc
{
  template<class K>
  struct BSTreeNode
  {
    typedef BSTreeNode<K> Node;
    Node* _left;
    Node* _right;
    K _key;
    BSTreeNode(const K& key)
      :_left(nullptr),
      _right(nullptr),
      _key(key)
    {}
  };
  template<class K>
  class BSTree
  {
    typedef BSTreeNode<K> Node;
  public:
    //强制生成默认构造
    BSTree() = default;
    //拷贝构造
    BSTree(const BSTree<K>& t)
    {
      _root = Copy(t._root);
    }
    //赋值
    BSTree<K>& operator=(BSTree<K> t)
    {
      swap(_root, t._root);
      return *this;
    }
    //析构
    ~BSTree()
    {
      Destory(_root);
      cout << "Destory()" << endl;
    }
    //查找
    bool Find(const K& key)
    {
      Node* cur = _root;
      while (cur)
      {
        if (cur->_key < key)
        {
          cur = cur->_right;
        }
        else if (cur->_key > key)
        {
          cur = cur->_left;
        }
        else
        {
          return true;
        }
      }
      return false;
    }
    //插入
    bool Insert(const K& key)
    {
      if (_root == nullptr)
      {
        _root = new Node(key);
        return true;
      }
      Node* parent = nullptr;
      Node* cur = _root;
      while (cur)
      {
        if (key > cur->_key)
        {
          parent = cur;
          cur = cur->_right;
        }
        else if (key < cur->_key)
        {
          parent = cur;
          cur = cur->_left;
        }
        else
        {
          return false;
        }
      }
      cur = new Node(key);
      if (key > parent->_key)
      {
        parent->_right = cur;
      }
      else
      {
        parent->_left = cur;
      }
      return true;
    }
    bool Erase(const K& key)
    {
      Node* parent = nullptr;
      Node* cur = _root;
      while (cur)
      {
        if (key > cur->_key)
        {
          parent = cur;
          cur = cur->_right;
        }
        else if (key < cur->_key)
        {
          parent = cur;
          cur = cur->_left;
        }
        else
        {
          if (cur->_left == nullptr)
          {
            if (cur == _root)
            {
              _root = cur->_right;
            }
            else
            {
              if (cur == parent->_right)
              {
                parent->_right = cur->_right;
              }
              else
              {
                parent->_left = cur->_right;
              }
            }
            delete cur;
            return true;
          }
          else if (cur->_right == nullptr)
          {
            if (cur == _root)
            {
              _root = cur->_left;
            }
            else
            {
              if (cur == parent->_left)
              {
                parent->_left = cur->_left;
              }
              else
              {
                parent->_right = cur->_left;
              }
            }
            delete cur;
            return true;
          }
          else
          {
            Node* rightMinParent = cur;
            Node* rightMin = cur->_right;
            while (rightMin->_left)
            {
              rightMinParent = rightMin;
              rightMin = rightMin->_left;
            }
            cur->_key = rightMin->_key;
            if (rightMin == rightMinParent->_left)
            {
              rightMinParent->_left = rightMin->_right;
            }
            else
            {
              rightMinParent->_right = rightMin->_right;
            }
            delete rightMin;
            return true;
          }
        }
      }
      return false;
    }
    //打印
    void InOrder()
    {
      _InOrder(_root);
      cout << endl;
    }
    
    bool FindR(const K& key)
    {
      return _FindR(_root, key);
    }
    bool InsertR(const K& key)
    {
      return _InsertR(_root, key);
    }
    bool EraseR(const K& key)
    {
      return _EraseR(_root, key);
    }
  private:
    bool _EraseR(Node*& root,const K& key)
    {
      if (root == nullptr)
        return false;
      if (root->_key < key)
        return _EraseR(root->_right, key);
      else if (root->_key > key)
        return _EraseR(root->_left, key);
      else
      {
        Node* del = root;
        if (root->_right == nullptr)
          root = root->_left;
        else if (root->_left == nullptr)
          root = root->_right;
        else
        {
          Node* rightMin = root->_right;
          while (rightMin->_left)
            rightMin = rightMin->_left;
          swap(root->_key, rightMin->_key);
          return _EraseR(root->_right, key);
        }
        delete del;
        return true;
      }
    }
    bool _InsertR(Node*& root, const K& key)
    {
      if (root == nullptr)
      {
        root = new Node(key);
        return true;
      }
      if (key > root->_key)
      {
        return _InsertR(root->_right, key);
      }
      else if (key < root->_key)
      {
        return _InsertR(root->_left, key);
      }
      else
      {
        return false;
      }
    }
    bool _FindR(Node* root, const K& key)
    {
      if (root == nullptr)
      {
        return false;
      }
      if (root->_key < key)
      {
        return _FindR(root->_right, key);
      }
      else if (root->_key > key)
      {
        return _FindR(root->_left, key);
      }
      else
      {
        return true;
      }
    
    }
    void Destory(Node* root)
    {
      if (root == nullptr)
        return;
      Destory(root->_left);
      Destory(root->_right);
      delete root;
    }
    Node* Copy(Node* root)
    {
      if (root == nullptr)
      {
        return nullptr;
      }
      Node* newRoot = new Node(root->_key);
      newRoot->_left = Copy(root->_left);
      newRoot->_right = Copy(root->_right);
      return newRoot;
    }
    void _InOrder(Node* root)
    {
      if (root == nullptr)
      {
        return;
      }
      _InOrder(root->_left);
      cout << root->_key << " ";
      _InOrder(root->_right);
    }
  private:
    Node* _root=nullptr;
  };
}
相关文章
|
8月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
178 12
|
8月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
160 10
|
编译器 C++
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
121 1
|
8月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
253 3
|
11月前
|
存储 算法 C++
【搜索算法】 跳马问题(C/C++)
【搜索算法】 跳马问题(C/C++)
|
11月前
|
人工智能 算法 Java
【搜索算法】数字游戏(C/C++)
【搜索算法】数字游戏(C/C++)
|
安全 算法 C语言
【C++进阶】深入STL之string:掌握高效字符串处理的关键
【C++进阶】深入STL之string:掌握高效字符串处理的关键
154 1
【C++进阶】深入STL之string:掌握高效字符串处理的关键
|
存储 C++
【C++】二叉树进阶之二叉搜索树(下)
【C++】二叉树进阶之二叉搜索树(下)
79 4
|
Java 编译器 C++
【C++】二叉树进阶之二叉搜索树(上)
【C++】二叉树进阶之二叉搜索树(上)
71 3
|
算法 C++
【C++高阶】高效搜索的秘密:深入解析搜索二叉树
【C++高阶】高效搜索的秘密:深入解析搜索二叉树
89 2