C++ --模拟实现搜索二叉树

简介: #搜索二叉树1. 搜索二叉树特点若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值每个结点的左右子树也分别为二叉搜索树

#搜索二叉树

1. 搜索二叉树特点

  • 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  • 每个结点的左右子树也分别为二叉搜索树

见一见:

微信图片_20230524001539.png

2. 操作分析

2.0 结点结构

template <class KEY>
struct node
{
  node<KEY>* _left;
  node<KEY>* _right;
  KEY _key;
  node(const KEY& key)
    :_left(nullptr)
    , _right(nullptr)
    , _key(key)
  {}
};
//声明:
//typedef struct node<KEY> node;
//typedef node* node_pointer;

2.1 插入

微信图片_20230524001718.png

  • 非递归插入
bool insert_nonRecurse(const KEY& key)
{
  //a. 树为空
  if (_root == nullptr)
  {
    _root = new node(key);
    return true;
  }
  //b. 树不为空,按性质插入
  node_pointer cur = _root;
  node_pointer parent = nullptr;
  //b.1 找合适位置
  while (cur != nullptr)
  {
    if (key > cur->_key) //b.1.1 key > cur->_key --> 右遍历
    {
      parent = cur;
      cur = cur->_right;
    }
    else if (key < cur->_key) //b.1.2 key < cur->_key --> 左遍历
    {
      parent = cur;
      cur = cur->_left;
    }
    else //b.1.3 相等 --> false
    {
      return false;
    }
  }
  //b.2 连接
  cur = new node(key);
  if (key > cur->_key)
  {
    parent->right = cur;
  }
  else
  {
    parent->_left = cur;
  }
  return true;
}
  • 递归插入
bool insert_recurse(node_pointer& root, const KEY& key)
{
  //a. 树为空
  if (root == nullptr)
  {
    root = new node(key);
    return true;
  }
  //b. 树不为空
  if (key > root->_key)  //右遍历
  {
    return insert_recurse(root->_right, key);
  }
  else if (key < root->_key) //左遍历
  {
    return insert_recurse(root->_left, key);
  }
  else //相等 --> false
  {
    return false;
  }
}
  • node_pointer& 理解
  • 微信图片_20230524001842.png

2.2 升序查看

void inOrder(node_pointer root)
{
  if (root == nullptr)
    return;
  _inOrder(root->_left);
  cout << root->_key << " ";
  _inOrder(root->_right);
}

2.3 查找

bool find(const KEY& key)
{
  node_pointer cur = _root;
  while (cur != nullptr)
  {
    if (key > cur->_key) //右遍历
    {
      cur = cur->_right;
    }
    else if (key < cur->_key) //左遍历
    {
      cur = cur->_left;
    }
    else
    {
      return true;
    }
  }
  return false;
}

2.4 删除

  • 非递归删除
  1. 删除左右子树都为空的节点(叶子节点)
  • 找到节点
  • 判断是否为头节点(直接删除,头节点置空)
  • 删除节点


微信图片_20230524002006.png

删除左子树为空,右子树不为空

找到节点

判断被删除节点是否为头节点(单独处理,头节点指向头节点右子树)

判断被删除节点在其父节点左子树还是右子树中(连接问题要分支考虑)

被删除节点在父节点左子树中(父节点左子树指向被删除节点右子树)

被删除节点在父节点右子树中(父节点右子树指向被删除节点右子树)

删除节点


微信图片_20230524002102.png

删除左子树不为空,右子树为空

找到节点

判断被删除节点是否为头节点(单独处理,头节点指向头节点左子树)

判断被删除节点在其父节点左子树还是右子树中(连接问题要分支考虑)

被删除节点在父节点左子树中(父节点左子树指向被删除节点左子树)

被删除节点在父节点右子树中(父节点右子树指向被删除节点左子树)

删除节点


微信图片_20230524002134.png微信图片_20230524002134.png

微信图片_20230524002134.png

删除左右子树都不为空(右子树最小值交换策略)

找到节点

取被删除节点右子树最小值节点并得到其最小值节点的父节点

被删除节点右子树最小值节点和被删除节点值交换(被删除节点变为原来右子树最小值节点位置)

其改变后的被删除节点在其父节点左子树还是右子树中(连接问题要分支考虑)

改变后的被删除节点在父节点左子树中(父节点左子树指向被删除节点右子树)

改变后的被删除节点在父节点右子树中(父节点右子树指向被删除节点右子树)

删除改变后的被删除节点

微信图片_20230524002251.png

bool erase_nonRecurse(const KEY& key)
{
  node_pointer parent = nullptr;
  node_pointer cur = _root;
  while (cur != nullptr)
  {
    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 (parent->_left == cur) //被删除节点在父节点左子树
          {
            parent->_left = cur->_right;
          }
          else //被删除节点在父节点右子树
          {
            parent->_right = cur->_right;
          }
        }
        delete cur;
      }
      else if (cur->_right == nullptr) //被删节点右子树为空 && 被删节点左右子树都为空
      {
        if (cur == _root) //头节点处理
        {
          _root = cur->_left;
        }
        else
        {
          if (parent->_left == cur) //被删除节点在父节点左子树
          {
            parent->_left = cur->_left;
          }
          else //被删除节点在父节点右子树
          {
            parent->_right = cur->_left;
          }
        }
        delete cur;
      }
      else //左右子树都不为空 (策略:右子树最小值交换)
      {
        node_pointer min_right = cur->_right;
        node_pointer parent_min_right = cur;
        while (min_right->_left) //取右子树最小值节点
        {
          parent_min_right = min_right;
          min_right = min_right->_left;
        }
        swap(min_right->_key, cur->_key);
        //被删除节点父节点和其节点右子树连接(支持原因:右子树最小值只可能拥有右子树不可能拥有左子树)
        if (parent_min_right->_left == min_right)  //右子树最小值节点(被删除节点)在其父节点左子树
        {
          parent_min_right->_left = min_right->_right;
        }
        else  //右子树最小值节点在其父节点右子树
        {
          parent_min_right->_right = min_right->_right;
        }
        delete min_right;
      }
      return true;
    }
  }
  return false;
}
  • 递归删除
bool _erase_Recurse(node_pointer& root, const KEY& key)
{
  if (root == nullptr)
  {
    return false;
  }
  if (key > root->_key) //右遍历
  {
    _erase_Recurse(root->_right, key);
  }
  else if (key < root->_key) //左遍历
  {
    _erase_Recurse(root->_left, key);
  }
  else //相等 --> 删除
  {
    node_pointer deleted_node = root;
    if (root->_left == nullptr) //被删节点左子树为空 && 被删节点左右子树都为空
    {
      root = root->_right;
    }
    else if (root->_right == nullptr) //被删节点右子树为空 && 被删节点左右子树都为空
    {
      root = root->_left;
    }
    else //左右子树都不为空(策略:右子树最小值和被删节点交换)
    {
      node_pointer min_right = root->_right;
      while (min_right->_left) //取被删节点右子树最小值
      {
        min_right = min_right->_left;
      }
      //交换数值
      swap(min_right->_key, root->_key);
      return _erase_Recurse(root->_right, key); //交换后删除值为min_right节点(右子树遍历)
    }
    delete deleted_node;
    return true;
  }
}
  • 删除小结
  • 首先考虑被删节点的左右子树都不为空&&被删节点的左子树为空右子树不为空&&被删节点的右子树为空左子树不为空&&被删节点左右子树都不为空四种情况(其中,被删节点的左子树为空右子树不为空&&被删节点的右子树为空左子树不为空包含被删节点的左右子树都不为空的情况)

2.5 前序拷贝构造

binary_search_tree(const binary_search_tree<KEY>& tree)
{
  _root = _copy(tree._root);
}
node_pointer _copy(node_pointer root)
{
  if (root == nullptr)
  {
    return nullptr;
  }
  node_pointer new_node = new node(root->_key);
  new_node->_left = _copy(root->_left);
  new_node->_right = _copy(root->_right);
  return new_node;
}

3. 完整代码

#pragma once
#include <iostream>
#include <algorithm>
#include <utility> 
using namespace std;
//模拟实现二叉搜索树
namespace my_tree
{
  template <class KEY>
  struct node
  {
    node<KEY>* _left;
    node<KEY>* _right;
    KEY _key;
    node(const KEY& key)
      :_left(nullptr)
      ,_right(nullptr)
      ,_key(key)
    {}
  };
  template <class KEY>
  class binary_search_tree
  {
  private:
    typedef node<KEY> node;
    typedef node* node_pointer;
  public:
    binary_search_tree()
      :_root(nullptr)
    {}
    binary_search_tree(const binary_search_tree<KEY>& tree)
    {
      _root = _copy(tree._root);
    }
    binary_search_tree<KEY>& operator=(binary_search_tree<KEY>& tree)
    {
      _swap(_root, tree._root);
      return *this;
    }
    ~binary_search_tree()
    {
      _destory(_root);
    }
    void _destory(node_pointer root)
    {
      if (root == nullptr)
      {
        return;
      }
      _destory(root->_left);
      _destory(root->_right);
      delete root;
      root = nullptr;
    }
    bool insert_nonRecurse(const KEY& key)
    {
      //a. 树为空
      if (_root == nullptr)
      {
        _root = new node(key);
        return true;
      }
      //b. 树不为空,按性质插入
      node_pointer cur = _root;
      node_pointer parent = nullptr;
      //b.1 找合适位置
      while (cur != nullptr) 
      {
        if (key > cur->_key) //b.1.1 key > cur->_key --> 右遍历
        {
          parent = cur;
          cur = cur->_right;
        }
        else if (key < cur->_key) //b.1.2 key < cur->_key --> 左遍历
        {
          parent = cur;
          cur = cur->_left;
        }
        else //b.1.3 相等 --> false
        {
          return false;
        }
      }
      //b.2 连接
      cur = new node(key);
      if (key > parent->_key) //b.2.1 key > parent_key --> 右连接
      {
        parent->_right = cur;
      }
      else //b.2.2 key < parent_key --> 左连接
      {
        parent->_left = cur;
      }
      return true;
    }
    bool insert_recurse(const KEY& key)
    {
      return _insert_recurse(_root, key);
    }
    bool find(const KEY& key)
    {
      node_pointer cur = _root;
      while (cur != nullptr)
      {
        if (key > cur->_key)
        {
          cur = cur->_right;
        }
        else if (key < cur->_key)
        {
          cur = cur->_left;
        }
        else
        {
          return true;
        }
      }
      return false;
    }
    bool erase_nonRecurse(const KEY& key)
    {
      node_pointer parent = nullptr;
      node_pointer cur = _root;
      while (cur != nullptr)
      { 
        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 (parent->_left == cur) //被删除节点在父节点左子树
              {
                parent->_left = cur->_right;
              }
              else //被删除节点在父节点右子树
              {
                parent->_right = cur->_right;
              }
            }
            delete cur;
          }
          else if (cur->_right == nullptr) //右子树为空 && 左右子树都为空
          { 
            if (cur == _root) //头节点处理
            {
              _root = cur->_left;
            }
            else
            {
              if (parent->_left == cur) //被删除节点在父节点左子树
              {
                parent->_left = cur->_left;
              }
              else //被删除节点在父节点右子树
              {
                parent->_right = cur->_left;
              }
            }
            delete cur;
          }
          else //左右子树都不为空 (策略:右子树最小值交换)
          {
            node_pointer min_right = cur->_right; 
            node_pointer parent_min_right = cur;
            while (min_right->_left) //取右子树最小值节点
            {
              parent_min_right = min_right;
              min_right = min_right->_left;
            }
            swap(min_right->_key, cur->_key); 
            //被删除节点父节点和其节点右子树连接(支持原因:右子树最小值只可能拥有右子树不可能拥有左子树)
            if (parent_min_right->_left == min_right)  //右子树最小值节点(被删除节点)在其父节点左子树
            {
              parent_min_right->_left = min_right->_right;
            }
            else  //右子树最小值节点在其父节点右子树
            {
              parent_min_right->_right = min_right->_right;
            }
            delete min_right;
          }
          return true;
        }
      }
      return false;
    }
    bool erase_Recurse(const KEY& key)
    {
      return _erase_Recurse(_root, key);
    }
    void inOrder()
    {
      _inOrder(_root);
      cout << endl;
    }
  private:
    void _inOrder(node_pointer root)
    {
      if (root == nullptr)
        return;
      _inOrder(root->_left);
      cout << root->_key << " ";
      _inOrder(root->_right);
    }
    bool _insert_recurse(node_pointer& root, const KEY& key)
    {
      //a. 树为空
      if (root == nullptr)
      {
        root = new node(key);
        return true;
      }
      //b. 树不为空
      if (key > root->_key)  //右遍历
      {
        return _insert_recurse(root->_right, key);
      }
      else if (key < root->_key) //左遍历
      {
        return _insert_recurse(root->_left, key);
      }
      else //相等 --> false
      {
        return false;
      }
    }
    bool _erase_Recurse(node_pointer& root, const KEY& key)
    {
      if (root == nullptr)
      {
        return false;
      }
      if (key > root->_key) //右遍历
      {
        _erase_Recurse(root->_right, key);
      }
      else if (key < root->_key) //左遍历
      {
        _erase_Recurse(root->_left, key);
      }
      else //相等 --> 删除
      {
        node_pointer deleted_node = root;
        if (root->_left == nullptr) //被删节点左子树为空 && 被删节点左右子树都为空
        {
          root = root->_right;
        }
        else if (root->_right == nullptr) //被删节点右子树为空 && 被删节点左右子树都为空
        {
          root = root->_left;
        }
        else //左右子树都不为空
        {
          node_pointer min_right = root->_right;
          while (min_right->_left) //取被删节点右子树最小值
          {
            min_right = min_right->_left;
          }
          //交换数值
          swap(min_right->_key, root->_key);
          return _erase_Recurse(root->_right, key);
        }
        delete deleted_node;
        return true;
      }
    }
    node_pointer _copy(node_pointer root)
    {
      if (root == nullptr)
      {
        return nullptr;
      }
      node_pointer new_node = new node(root->_key);
      new_node->_left = _copy(root->_left);
      new_node->_right = _copy(root->_right);
      return new_node;
    }
    void _swap(node_pointer& self, node_pointer& other)
    {
      node_pointer tmp = self;
      self = other;
      other = tmp;
    }
    private:
      node_pointer _root;
  };
}

4. 时间复杂度分析

微信图片_20230524002522.png

增删查改时间复杂度:O(N)

5. 简单应用

5.1 字典搜索

namespace key_value
{
  template <class KEY, class VALUE>
  struct node
  {
    struct node<KEY, VALUE>* _left;
    struct node<KEY, VALUE>* _right;
    KEY _key;
    VALUE _value;
    node(const KEY& key, const VALUE& value)
      :_left(nullptr)
      , _right(nullptr)
      , _key(key)
      , _value(value)
    {}
  };
  template <class KEY, class VALUE>
  class binary_search_tree
  {
  private:
    typedef struct node<KEY, VALUE> node;
    typedef node* node_pointer;
  public:
    binary_search_tree()
      :_root(nullptr)
    {}
    ~binary_search_tree()
    {
      _destory(_root);
    }
    void _destory(node_pointer root)
    {
      if (root == nullptr)
      {
        return;
      }
      _destory(root->_left);
      _destory(root->_right);
      delete root;
      root = nullptr;
    }
    bool insert_nonRecurse(const KEY& key, const VALUE& value)
    {
      //a. 树为空
      if (_root == nullptr)
      {
        _root = new node(key, value);
        return true;
      }
      //b. 树不为空,按性质插入
      node_pointer cur = _root;
      node_pointer parent = nullptr;
      //b.1 找合适位置
      while (cur != nullptr)
      {
        if (key > cur->_key) //b.1.1 key > cur->_key --> 右遍历
        {
          parent = cur;
          cur = cur->_right;
        }
        else if (key < cur->_key) //b.1.2 key < cur->_key --> 左遍历
        {
          parent = cur;
          cur = cur->_left;
        }
        else //b.1.3 相等 --> false
        {
          return false;
        }
      }
      //b.2 连接
      cur = new node(key, value);
      if (key > parent->_key) //b.2.1 key > parent_key --> 右连接
      {
        parent->_right = cur;
      }
      else //b.2.2 key < parent_key --> 左连接
      {
        parent->_left = cur;
      }
      return true;
    }
    node_pointer find(const KEY& key)
    {
      node_pointer cur = _root;
      while (cur != nullptr)
      {
        if (key > cur->_key)
        {
          cur = cur->_right;
        }
        else if (key < cur->_key)
        {
          cur = cur->_left;
        }
        else
        {
          return cur;
        }
      }
      return nullptr;
    }
    bool erase_nonRecurse(const KEY& key)
    {
      node_pointer parent = nullptr;
      node_pointer cur = _root;
      while (cur != nullptr)
      {
        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 (parent->_left == cur) //被删除节点在父节点左子树
              {
                parent->_left = cur->_right;
              }
              else //被删除节点在父节点右子树
              {
                parent->_right = cur->_right;
              }
            }
            delete cur;
          }
          else if (cur->_right == nullptr) //右子树为空 && 左右子树都为空
          {
            if (cur == _root) //头节点处理
            {
              _root = cur->_left;
            }
            else
            {
              if (parent->_left == cur) //被删除节点在父节点左子树
              {
                parent->_left = cur->_left;
              }
              else //被删除节点在父节点右子树
              {
                parent->_right = cur->_left;
              }
            }
            delete cur;
          }
          else //左右子树都不为空 (策略:右子树最小值交换)
          {
            node_pointer min_right = cur->_right;
            node_pointer parent_min_right = cur;
            while (min_right->_left) //取右子树最小值节点
            {
              parent_min_right = min_right;
              min_right = min_right->_left;
            }
            swap(min_right->_key, cur->_key);
            //被删除节点父节点和其节点右子树连接(支持原因:右子树最小值只可能拥有右子树不可能拥有左子树)
            if (parent_min_right->_left == min_right)  //右子树最小值节点(被删除节点)在其父节点左子树
            {
              parent_min_right->_left = min_right->_right;
            }
            else  //右子树最小值节点在其父节点右子树
            {
              parent_min_right->_right = min_right->_right;
            }
            delete min_right;
          }
          return true;
        }
      }
      return false;
    }
    void inOrder()
    {
      _inOrder(_root);
      cout << endl;
    }
  private:
    void _inOrder(node_pointer root)
    {
      if (root == nullptr)
        return;
      _inOrder(root->_left);
      cout << root->_key << " " << root->_value << endl;
      _inOrder(root->_right);
    }
  private:
    node_pointer _root;
  };
  void test()
  {
    binary_search_tree<string, string> dict;
    dict.insert_nonRecurse("apple", "苹果");
    dict.insert_nonRecurse("banana", "香蕉");
    dict.insert_nonRecurse("pear", "梨子");
    dict.insert_nonRecurse("orange", "橙子");
    dict.insert_nonRecurse("strawberry", "草莓");
    dict.insert_nonRecurse("pitaya", "火龙果");
    dict.insert_nonRecurse("tangerine", "橘子");
    string str;
    while (cin >> str)
    {
      node<string, string>* ret = dict.find(str);
      if (ret != nullptr)
        cout << ret->_key << "->" << ret->_value << endl;
      else
        cout << "找不到" << endl;
    }
  }
}

5.2 统计次数

namespace key_value
{
  template <class KEY, class VALUE>
  struct node
  {
    struct node<KEY, VALUE>* _left;
    struct node<KEY, VALUE>* _right;
    KEY _key;
    VALUE _value;
    node(const KEY& key, const VALUE& value)
      :_left(nullptr)
      , _right(nullptr)
      , _key(key)
      , _value(value)
    {}
  };
  template <class KEY, class VALUE>
  class binary_search_tree
  {
  private:
    typedef struct node<KEY, VALUE> node;
    typedef node* node_pointer;
  public:
    binary_search_tree()
      :_root(nullptr)
    {}
    ~binary_search_tree()
    {
      _destory(_root);
    }
    void _destory(node_pointer root)
    {
      if (root == nullptr)
      {
        return;
      }
      _destory(root->_left);
      _destory(root->_right);
      delete root;
      root = nullptr;
    }
    bool insert_nonRecurse(const KEY& key, const VALUE& value)
    {
      //a. 树为空
      if (_root == nullptr)
      {
        _root = new node(key, value);
        return true;
      }
      //b. 树不为空,按性质插入
      node_pointer cur = _root;
      node_pointer parent = nullptr;
      //b.1 找合适位置
      while (cur != nullptr)
      {
        if (key > cur->_key) //b.1.1 key > cur->_key --> 右遍历
        {
          parent = cur;
          cur = cur->_right;
        }
        else if (key < cur->_key) //b.1.2 key < cur->_key --> 左遍历
        {
          parent = cur;
          cur = cur->_left;
        }
        else //b.1.3 相等 --> false
        {
          return false;
        }
      }
      //b.2 连接
      cur = new node(key, value);
      if (key > parent->_key) //b.2.1 key > parent_key --> 右连接
      {
        parent->_right = cur;
      }
      else //b.2.2 key < parent_key --> 左连接
      {
        parent->_left = cur;
      }
      return true;
    }
    node_pointer find(const KEY& key)
    {
      node_pointer cur = _root;
      while (cur != nullptr)
      {
        if (key > cur->_key)
        {
          cur = cur->_right;
        }
        else if (key < cur->_key)
        {
          cur = cur->_left;
        }
        else
        {
          return cur;
        }
      }
      return nullptr;
    }
    bool erase_nonRecurse(const KEY& key)
    {
      node_pointer parent = nullptr;
      node_pointer cur = _root;
      while (cur != nullptr)
      {
        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 (parent->_left == cur) //被删除节点在父节点左子树
              {
                parent->_left = cur->_right;
              }
              else //被删除节点在父节点右子树
              {
                parent->_right = cur->_right;
              }
            }
            delete cur;
          }
          else if (cur->_right == nullptr) //右子树为空 && 左右子树都为空
          {
            if (cur == _root) //头节点处理
            {
              _root = cur->_left;
            }
            else
            {
              if (parent->_left == cur) //被删除节点在父节点左子树
              {
                parent->_left = cur->_left;
              }
              else //被删除节点在父节点右子树
              {
                parent->_right = cur->_left;
              }
            }
            delete cur;
          }
          else //左右子树都不为空 (策略:右子树最小值交换)
          {
            node_pointer min_right = cur->_right;
            node_pointer parent_min_right = cur;
            while (min_right->_left) //取右子树最小值节点
            {
              parent_min_right = min_right;
              min_right = min_right->_left;
            }
            swap(min_right->_key, cur->_key);
            //被删除节点父节点和其节点右子树连接(支持原因:右子树最小值只可能拥有右子树不可能拥有左子树)
            if (parent_min_right->_left == min_right)  //右子树最小值节点(被删除节点)在其父节点左子树
            {
              parent_min_right->_left = min_right->_right;
            }
            else  //右子树最小值节点在其父节点右子树
            {
              parent_min_right->_right = min_right->_right;
            }
            delete min_right;
          }
          return true;
        }
      }
      return false;
    }
    void inOrder()
    {
      _inOrder(_root);
      cout << endl;
    }
  private:
    void _inOrder(node_pointer root)
    {
      if (root == nullptr)
        return;
      _inOrder(root->_left);
      cout << root->_key << " " << root->_value << endl;
      _inOrder(root->_right);
    }
  private:
    node_pointer _root;
  };
  void test()
  {
    string arr[] = { "西瓜", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉", "梨" }; 
    key_value::binary_search_tree<string, int> countTree;
    for (auto str : arr)
    {
      auto ret = countTree.find(str);
      if (ret == nullptr)
      {
        countTree.insert_nonRecurse(str, 1);
      }
      else
      {
        ret->_value++;
      }
    }
    countTree.inOrder();
  }
}































相关文章
|
2月前
|
C++
二叉树进阶面试题(精华总结)【C++版本】
二叉树进阶面试题(精华总结)【C++版本】
|
2月前
|
存储 编译器 数据库
【C/C++ 数据结构 】线索二叉树全解析:从数学原理到C++实现
【C/C++ 数据结构 】线索二叉树全解析:从数学原理到C++实现
55 0
|
2月前
|
算法 C++ 开发者
【C/C++ 数据结构 】二叉树基本性质:对于任何一颗二叉树T,若其终端结点为n0 ,那么度数为2的结点数为n2。则n0=n2+1...
【C/C++ 数据结构 】二叉树基本性质:对于任何一颗二叉树T,若其终端结点为n0 ,那么度数为2的结点数为n2。则n0=n2+1...
16 0
|
16天前
|
存储 C++
二叉树的操作(C++实现)
二叉树的操作(C++实现)
|
2月前
|
存储 C++
【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)
【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)
【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)
|
2月前
|
存储 算法 数据管理
C++中利用随机策略优化二叉树操作效率的实现方法
C++中利用随机策略优化二叉树操作效率的实现方法
77 1
|
2月前
|
算法 C++ 开发者
【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
13 0
|
2月前
|
存储 算法 C语言
【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
60 0
|
2月前
|
存储 算法 数据管理
【C++入门到精通】C++入门 ——搜索二叉树(二叉树进阶)
在C++中,本文介绍了搜索二叉树(二叉搜索树,BST)的概念和基本操作,包括搜索、插入和删除。搜索操作从根节点开始,按值大小决定左右查找;插入操作找到合适位置新建节点;删除操作需考虑无子节点、单子节点和双子节点的情况。文中还提供了非递归和递归实现的C++代码示例。此外,讨论了搜索二叉树在K模型和KV模型中的应用以及性能分析,强调了保持树平衡的重要性。
16 0
|
2月前
|
C++
C++进阶--搜索二叉树
C++进阶--搜索二叉树