【c++】搜索二叉树的模拟实现

搜索二叉树的模拟实现

k模型完整代码

#pragma once
namespace hqj1
{
 template<class K>
 struct SBTreeNode
 {
 public:
  //这里直接用匿名对象作为缺省参数
  SBTreeNode(const K& key = K())
   :_key(key)
   , _cleft(nullptr)
   , _cright(nullptr)
  {}
 public:
  K _key;
  SBTreeNode* _cleft;
  SBTreeNode* _cright;
 };

 template<class K>
 class SBTree
 {
  typedef SBTreeNode<K> Node;
 public:
  SBTree()
   :_root(nullptr)
  {}

  bool Insert(const K& key)
  {
   if (_root == nullptr)
    _root = new Node(key);
   else
   {
    Node* cur = _root;
    Node* parent = nullptr;
    //找到要插入的位置
    while (cur)
    {
     parent = cur;
     if (cur->_key < key)
      cur = cur->_cright;
     else if (cur->_key > key)
      cur = cur->_cleft;
     else
      return false;
    }

    //连接
    cur = new Node(key);
    if (parent->_key < key)
     parent->_cright = cur;
    else
     parent->_cleft = cur;
   }
   return true;
  }

  Node* Find(const K& key)
  {
   Node* cur = _root;
   while (cur)
   {
    if (key > cur->_key)
     cur = cur->_cright;
    else if (key < cur->_key)
     cur = cur->_cleft;
    else
     break;
   }
   return cur;
  }

  bool Erase(const K& key)
  {
   if (_root == nullptr)
    return false;
   else
   {
    //找出要删除元素的位置,复用查找函数也行
    Node* cur = _root;
    Node* parent = nullptr;
    while (cur)
    {
     if (cur->_key == key)
      break;

     parent = cur;
     if (key > cur->_key)
      cur = cur->_cright;
     else if (key < cur->_key)
      cur = cur->_cleft;
    }

    //对根进行特判
    if (parent == nullptr)
    {
     if (cur->_cleft == nullptr && cur->_cright == nullptr)
     {
      delete _root;
      _root = nullptr;
     }
     else if (cur->_cleft == nullptr)
      _root = _root->_cright;
     else
      _root = _root->_cleft;

     return true;
    }

    //对不同情况进行处理
    //第一种是要删除的元素不在树内
    if (cur == nullptr)
     return false;
    else if (cur->_cleft == nullptr && cur->_cleft == cur->_cright)
    {
     //要删除的元素是叶子节点,直接删
     if (cur == parent->_cleft)
      parent->_cleft = nullptr;
     else
      parent->_cright = nullptr;

     delete cur;
    }
    else if (cur->_cleft == nullptr)
    {
     //有右子树但没有左子树
     if (cur == parent->_cleft)
      parent->_cleft = cur->_cright;
     else
      parent->_cright = cur->_cright;

     delete cur;
    }
    else if (cur->_cright == nullptr)
    {
     //有左子树但没有右子树
     if (cur == parent->_cleft)
     {
      parent->_cleft = cur->_cleft;
     }
     else
     {
      parent->_cright = cur->_cleft;
     }
     delete cur;
    }
    else
    {
     //既有左子树又有右子树
     //找左子树的最右,或者找右子树的最左节点来替换掉当前要删除的节点
     Node* curRL = cur->_cright;
     Node* parentRL = cur;
     while (curRL->_cleft)
     {
      parentRL = curRL;
      curRL = curRL->_cleft;
     }
     //交换要删除的值和要删除节点的右树最左节点的值
     swap(cur->_key, curRL->_key);
     //判断要删除的节点在其父节点的位置
     //操控父节点指针
     //有一个性质:右子树中的最左节点一定没有左子树,我们让父节点连接要删除节点的右子树就行
     if (curRL == parentRL->_cleft)
      parentRL->_cleft = curRL->_cright;
     else
      parentRL->_cright = curRL->_cright;
     delete curRL;
     curRL = nullptr;
    }
    return true;
   }
  }

  void InOrder()
  {
   _InOrder(_root);
  }
 private:
  void _InOrder(const Node* root)
  {
   if (root == nullptr)
    return;

   _InOrder(root->_cleft);
   cout << root->_key << ' ';
   _InOrder(root->_cright);
  }
  Node* _root;
 };
}

k模型节点的定义

  • 这是一个模板类,模板类型为K,代表着关键词

  • 成员为:关键词、左子树指针、右子树指针

  • 构造函数的参数为K类型的对象,缺省参数为匿名对象(K()),使我们代码的通用性增强

    template<class K>
    struct SBTreeNode
    {
    public:
    //这里直接用匿名对象作为缺省参数
    SBTreeNode(const K& key = K())
    :_key(key)
    , _cleft(nullptr)
    , _cright(nullptr)
    {}
    public:
    K _key;
    SBTreeNode* _cleft;
    SBTreeNode* _cright;
    };

k模型二叉搜索树类的实现

  • 首先将节点类类型重定义为Node方便我们后续的使用

  • 成员函数为插入、删除、查找、中序遍历

  • 私有成员为节点指针_root

    template<class K>
    class SBTree
    {
    typedef SBTreeNode<K> Node;
    public:
    SBTree()
    :_root(nullptr)
    {}

    bool Insert(const K& key)
    {
     if (_root == nullptr)
      _root = new Node(key);
     else
     {
      Node* cur = _root;
      Node* parent = nullptr;
      //找到要插入的位置
      while (cur)
      {
       parent = cur;
       if (cur->_key < key)
        cur = cur->_cright;
       else if (cur->_key > key)
        cur = cur->_cleft;
       else
        return false;
      }
    
      //连接
      cur = new Node(key);
      if (parent->_key < key)
       parent->_cright = cur;
      else
       parent->_cleft = cur;
     }
     return true;
    }
    
    Node* Find(const K& key)
    {
     Node* cur = _root;
     while (cur)
     {
      if (key > cur->_key)
       cur = cur->_cright;
      else if (key < cur->_key)
       cur = cur->_cleft;
      else
       break;
     }
     return cur;
    }
    
    bool Erase(const K& key)
    {
     if (_root == nullptr)
      return false;
     else
     {
      //找出要删除元素的位置,复用查找函数也行
      Node* cur = _root;
      Node* parent = nullptr;
      while (cur)
      {
       if (cur->_key == key)
        break;
    
       parent = cur;
       if (key > cur->_key)
        cur = cur->_cright;
       else if (key < cur->_key)
        cur = cur->_cleft;
      }
    
      //对根进行特判
      if (parent == nullptr)
      {
       if (cur->_cleft == nullptr && cur->_cright == nullptr)
       {
        delete _root;
        _root = nullptr;
       }
       else if (cur->_cleft == nullptr)
        _root = _root->_cright;
       else
        _root = _root->_cleft;
    
       return true;
      }
    
      //对不同情况进行处理
      //第一种是要删除的元素不在树内
      if (cur == nullptr)
       return false;
      else if (cur->_cleft == nullptr && cur->_cleft == cur->_cright)
      {
       //要删除的元素是叶子节点,直接删
       if (cur == parent->_cleft)
        parent->_cleft = nullptr;
       else
        parent->_cright = nullptr;
    
       delete cur;
      }
      else if (cur->_cleft == nullptr)
      {
       //有右子树但没有左子树
       if (cur == parent->_cleft)
        parent->_cleft = cur->_cright;
       else
        parent->_cright = cur->_cright;
    
       delete cur;
      }
      else if (cur->_cright == nullptr)
      {
       //有左子树但没有右子树
       if (cur == parent->_cleft)
       {
        parent->_cleft = cur->_cleft;
       }
       else
       {
        parent->_cright = cur->_cleft;
       }
       delete cur;
      }
      else
      {
       //既有左子树又有右子树
       //找左子树的最右,或者找右子树的最左节点来替换掉当前要删除的节点
       Node* curRL = cur->_cright;
       Node* parentRL = cur;
       while (curRL->_cleft)
       {
        parentRL = curRL;
        curRL = curRL->_cleft;
       }
       //交换要删除的值和要删除节点的右树最左节点的值
       swap(cur->_key, curRL->_key);
       //判断要删除的节点在其父节点的位置
       //操控父节点指针
       //有一个性质:右子树中的最左节点一定没有左子树,我们让父节点连接要删除节点的右子树就行
       if (curRL == parentRL->_cleft)
        parentRL->_cleft = curRL->_cright;
       else
        parentRL->_cright = curRL->_cright;
       delete curRL;
       curRL = nullptr;
      }
      return true;
     }
    }
    
    void InOrder()
    {
     _InOrder(_root);
    }
    

    private:
    void _InOrder(const Node* root)
    {
    if (root == nullptr)
    return;

     _InOrder(root->_cleft);
     cout << root->_key << ' ';
     _InOrder(root->_cright);
    }
    Node* _root;
    

    };

构造函数

  • 将_root指针初始化为空指针即可

    SBTree()
    :_root(nullptr)
    {}

Insert函数

  • Insert函数的参数为要插入的关键字

  • 首先进行判空,如果_root为空,说明此时还没有节点,我们直接给_root赋值就行

  • 如果不为空,那么就需要先找到要插入的位置,我们定义cur和parent两个节点指针,cur负责寻找要插入的位置,parent负责记录cur的父亲节点,由于搜索二叉树的特性,当key值大于cur所指向节点的_key值说明要插入的位置再cur节点的右子树中,反之则在cur的左子树中,通过循环来达到目的,更新cur的同时要更新parent

  • 如果遇到cur的_key和key相等的情况说明插入失败,其余情况皆为插入成功

    bool Insert(const K& key)
    {
    if (_root == nullptr)
    _root = new Node(key);
    else
    {
    Node* cur = _root;
    Node* parent = nullptr;
    //找到要插入的位置
    while (cur)
    {
    if (cur->_key == key)
    return false;

       parent = cur;
       if (cur->_key < key)
        cur = cur->_cright;
       else if (cur->_key > key)
        cur = cur->_cleft;
      }
    
      //连接
      cur = new Node(key);
      if (parent->_key < key)
       parent->_cright = cur;
      else
       parent->_cleft = cur;
     }
     return true;
    }
    

Find函数

  • Find的参数为要查找的关键字

  • 我们定义cur指针来找到目标节点位置,当key > cur->_key时cur要往其右子树寻找,反之则去其左子树寻找,当相等时或者cur指向空(意味着没找到)结束循环,返回cur

    Node* Find(const K& key)
    {
     Node* cur = _root;
     while (cur)
     {
      if (key > cur->_key)
       cur = cur->_cright;
      else if (key < cur->_key)
       cur = cur->_cleft;
      else
       break;
     }
     return cur;
    }
    

Erase函数

  • 该函数的参数为要删除的关键字

  • 当要操作的树为空树时,直接返回失败

  • 不是空树则首先找出要删除节点的位置,同样是定义cur和parent节点指针,cur负责找出要删除节点的位置,parent负责记录cur节点的父节点。利用循环结构实现,循环的结束条件为cur为空指针或者找到对应位置,若为空则说明要删除节点不在树内,直接返回失败

  • 找到之后首先判断是否要操作_root指针,当parent为空时说明要操作根节点,对于根节点的不同类型进行对应的操作1. 如果整棵树只有一个节点,直接删除根节点,并将根节点置为空。2. 如果根节点没有左子树,则用右子树的根节点作为新的整棵树的根节点。3. 如果根节点没有右子树,则用左子树的根节点作为新的整棵树的根节点。4. 如果根节点既有左子树又有右子树,则当作普通节点处理(见下一点的第4小点)

  • 处理完根节点问题后就改判断要删除的节点是哪种类型:1. 删除节点是叶子结点,那么我们直接删除该节点并更新其父亲节点的指针(判断要删除节点是其父情节点的左子树还是右子树,操作对应的指针)2. 有右子树但没有左子树,让其父亲的对应指针指向其右子树,并删除当前节点。3. 有左子树但没有右子树,让其父亲的对应指针指向其左子树,并删除该节点4. 既有左子树又有右子树,定义curRL负责寻找其右子树的最左节点(也就是右子树的最小节点)或者定义curLR左子树的最右节点(也就是左子树的最大节点),定义parentRL记录其父亲节点,与当前节点(cur)的值进行交换,交换完后令parentRL的对应指针指向curRL的右子树,并删除curRL所指向的节点。

  • 所有过程走完后返回状态(成功或者失败)

    bool Erase(const K& key)
    {
    if (_root == nullptr)
    return false;
    else
    {
    //找出要删除元素的位置,复用查找函数也行
    Node* cur = _root;
    Node* parent = nullptr;
    while (cur)
    {
    if (cur->_key == key)
    break;

       parent = cur;
       if (key > cur->_key)
        cur = cur->_cright;
       else if (key < cur->_key)
        cur = cur->_cleft;
      }
    
      //对根进行特判
      if (parent == nullptr)
      {
       if (cur->_cleft == nullptr && cur->_cright == nullptr)
       {
        delete _root;
        _root = nullptr;
       }
       else if (cur->_cleft == nullptr)
        _root = _root->_cright;
       else
        _root = _root->_cleft;
    
       return true;
      }
    
      //对不同情况进行处理
      //第一种是要删除的元素不在树内
      if (cur == nullptr)
       return false;
      else if (cur->_cleft == nullptr && cur->_cleft == cur->_cright)
      {
       //要删除的元素是叶子节点,直接删
       if (cur == parent->_cleft)
        parent->_cleft = nullptr;
       else
        parent->_cright = nullptr;
    
       delete cur;
      }
      else if (cur->_cleft == nullptr)
      {
       //有右子树但没有左子树
       if (cur == parent->_cleft)
        parent->_cleft = cur->_cright;
       else
        parent->_cright = cur->_cright;
    
       delete cur;
      }
      else if (cur->_cright == nullptr)
      {
       //有左子树但没有右子树
       if (cur == parent->_cleft)
       {
        parent->_cleft = cur->_cleft;
       }
       else
       {
        parent->_cright = cur->_cleft;
       }
       delete cur;
      }
      else
      {
       //既有左子树又有右子树
       //找左子树的最右,或者找右子树的最左节点来替换掉当前要删除的节点
       Node* curRL = cur->_cright;
       Node* parentRL = cur;
       while (curRL->_cleft)
       {
        parentRL = curRL;
        curRL = curRL->_cleft;
       }
       //交换要删除的值和要删除节点的右树最左节点的值
       swap(cur->_key, curRL->_key);
       //判断要删除的节点在其父节点的位置
       //操控父节点指针
       //有一个性质:右子树中的最左节点一定没有左子树,我们让父节点连接要删除节点的右子树就行
       if (curRL == parentRL->_cleft)
        parentRL->_cleft = curRL->_cright;
       else
        parentRL->_cright = curRL->_cright;
       delete curRL;
       curRL = nullptr;
      }
      return true;
     }
    }
    

kv模型完整代码

#pragma once
namespace hqj2
{
 template<class K, class V>
 struct SBTreeNode
 {
 public:
  SBTreeNode(const K& key = K(), const V& value = V())
   :_cleft(nullptr), _cright(nullptr)
   , _key(key)
   , _value(value)
  {}
 public:
  SBTreeNode* _cleft;
  SBTreeNode* _cright;
  K _key;
  V _value;
 };

 template<class K, class V>
 class SBTree
 {
  typedef SBTreeNode<K, V> Node;
 public:
  SBTree()
   :_root(nullptr)
  {}
 public:
  bool Insert(const K& key, const V& value)
  {
   if (_root == nullptr)
    _root = new Node(key, value);
   else
   {
    Node* cur = _root;
    Node* parent = nullptr;

    while (cur)
    {
     if (cur->_key == key)
      return false;
     parent = cur;
     if (key > cur->_key)
      cur = cur->_cright;
     else if (key < cur->_key)
      cur = cur->_cleft;
    }

    cur = new Node(key, value);
    if (cur == parent->_cleft)
     parent->_cleft = cur;
    else
     parent->_cright = cur;
   }
   return true;
  }

  void InOrder()
  {
   _Inorder(_root);
  }

  Node*& Find(const K& key)
  {
   Node* cur = _root;

   while (cur)
   {
    if (key > cur->_key)
     cur = cur->_cright;
    else if (key < cur->_key)
     cur = cur->_cleft;
    else
     break;
   }

   return cur;
  }

  bool Erase(const K& key)
  {
   if (_root == nullptr)
    return false;

   Node* cur = _root;
   Node* parent = nullptr;

   while (cur)
   {
    if (cur->_key == key)
     break;

    parent = cur;
    if (key > cur->_key)
     cur = cur->_cright;
    else if (key < cur->_key)
     cur = cur->_cleft;
   }

   if (parent == nullptr)
   {
    if (cur->_cleft == nullptr && cur->_cright == nullptr)
    {
     delete _root;
     _root = nullptr;
    }
    else if (cur->_cleft == nullptr)
     _root = _root->_cright;
    else
     _root = _root->_cleft;
    return true;
   }

   if (cur->_cleft == nullptr && cur->_cright == nullptr)
   {
    if (cur == parent->_cleft)
     parent->_cleft = nullptr;
    else
     parent->_cright = nullptr;

    delete cur;
   }
   else if (cur->_cleft == nullptr)
   {
    if (cur == parent->_cleft)
     parent->_cleft = cur->_cright;
    else
     parent->_cright = cur->_cright;

    delete cur;
   }
   else if (cur->_cright == nullptr)
   {
    if (cur == parent->_cleft)
     parent->_cleft = cur->_cleft;
    else
     parent->_cright = cur->_cleft;
   }
   else
   {
    Node* parntRL = nullptr;
    Node* curRL = cur->_cright;

    while (curRL->_cleft != nullptr)
    {
     parntRL = curRL;
     curRL = curRL->_cleft;
    }

    swap(curRL->_key, cur->_key);

    if (curRL == parntRL->_cleft)
     parntRL->_cleft = curRL->_cright;
    else
     parntRL->_cright = curRL->_cright;
    delete curRL;
   }
   return true;
  }
 private:
  void _Inorder(const Node* root)
  {
   if (root == nullptr)
    return;
   _Inorder(root->_cleft);
   cout << root->_key << ' ' << root->_value << ' ' << endl;
   _Inorder(root->_cright);
  }

  Node* _root;
 };
}

kv模型搜索二叉树的定义

  • 是模板类,模板参数是K和V

  • 成员函数和k模型一模一样

    template<class K, class V>
    class SBTree
    {
    typedef SBTreeNode<K, V> Node;
    public:
    SBTree()
    :_root(nullptr)
    {}
    public:
    bool Insert(const K& key, const V& value)
    {
    if (_root == nullptr)
    _root = new Node(key, value);
    else
    {
    Node* cur = _root;
    Node* parent = nullptr;

      while (cur)
      {
       if (cur->_key == key)
        return false;
       parent = cur;
       if (key > cur->_key)
        cur = cur->_cright;
       else if (key < cur->_key)
        cur = cur->_cleft;
      }
    
      cur = new Node(key, value);
      if (cur == parent->_cleft)
       parent->_cleft = cur;
      else
       parent->_cright = cur;
     }
     return true;
    }
    
    void InOrder()
    {
     _Inorder(_root);
    }
    
    Node*& Find(const K& key)
    {
     Node* cur = _root;
    
     while (cur)
     {
      if (key > cur->_key)
       cur = cur->_cright;
      else if (key < cur->_key)
       cur = cur->_cleft;
      else
       break;
     }
    
     return cur;
    }
    
    bool Erase(const K& key)
    {
     if (_root == nullptr)
      return false;
    
     Node* cur = _root;
     Node* parent = nullptr;
    
     while (cur)
     {
      if (cur->_key == key)
       break;
    
      parent = cur;
      if (key > cur->_key)
       cur = cur->_cright;
      else if (key < cur->_key)
       cur = cur->_cleft;
     }
    
     if (parent == nullptr)
     {
      if (cur->_cleft == nullptr && cur->_cright == nullptr)
      {
       delete _root;
       _root = nullptr;
      }
      else if (cur->_cleft == nullptr)
       _root = _root->_cright;
      else
       _root = _root->_cleft;
      return true;
     }
    
     if (cur->_cleft == nullptr && cur->_cright == nullptr)
     {
      if (cur == parent->_cleft)
       parent->_cleft = nullptr;
      else
       parent->_cright = nullptr;
    
      delete cur;
     }
     else if (cur->_cleft == nullptr)
     {
      if (cur == parent->_cleft)
       parent->_cleft = cur->_cright;
      else
       parent->_cright = cur->_cright;
    
      delete cur;
     }
     else if (cur->_cright == nullptr)
     {
      if (cur == parent->_cleft)
       parent->_cleft = cur->_cleft;
      else
       parent->_cright = cur->_cleft;
     }
     else
     {
      Node* parntRL = nullptr;
      Node* curRL = cur->_cright;
    
      while (curRL->_cleft != nullptr)
      {
       parntRL = curRL;
       curRL = curRL->_cleft;
      }
    
      swap(curRL->_key, cur->_key);
    
      if (curRL == parntRL->_cleft)
       parntRL->_cleft = curRL->_cright;
      else
       parntRL->_cright = curRL->_cright;
      delete curRL;
     }
     return true;
    }
    

    private:
    void _Inorder(const Node* root)
    {
    if (root == nullptr)
    return;
    _Inorder(root->_cleft);
    cout << root->_key << ' ' << root->_value << ' ' << endl;
    _Inorder(root->_cright);
    }

    Node* _root;
    

    };

kv模型节点的定义

  • 节点是模板类,模板参数为K和V

  • 成员为左子树指针、右子树指针、关键字、所对应的值

  • 依然以匿名对象作为缺省参数,使得我们程序更加通用

    template<class K, class V>
    struct SBTreeNode
    {
    public:
    SBTreeNode(const K& key = K(), const V& value = V())
    :_cleft(nullptr), _cright(nullptr)
    , _key(key)
    , _value(value)
    {}
    public:
    SBTreeNode* _cleft;
    SBTreeNode* _cright;
    K _key;
    V _value;
    };

Insert函数

  • 该函数参数为关键字、值

  • 首先判断该树有无节点,无节点则直接给_root赋值,有节点则先找要插入的位置,插入的同时改变其父亲节点所对应的指针

  • 返回值为插入状态

    bool Insert(const K& key, const V& value)
    {
    if (_root == nullptr)
    _root = new Node(key, value);
    else
    {
    Node* cur = _root;
    Node* parent = nullptr;

      while (cur)
      {
       if (cur->_key == key)
        return false;
       parent = cur;
       if (key > cur->_key)
        cur = cur->_cright;
       else if (key < cur->_key)
        cur = cur->_cleft;
      }
    
      cur = new Node(key, value);
      if (cur == parent->_cleft)
       parent->_cleft = cur;
      else
       parent->_cright = cur;
     }
     return true;
    }
    

Find函数

  • 和k模型的一模一样,不做赘述

    Node*& Find(const K& key)
    {
    Node* cur = _root;

     while (cur)
     {
      if (key > cur->_key)
       cur = cur->_cright;
      else if (key < cur->_key)
       cur = cur->_cleft;
      else
       break;
     }
    
     return cur;
    }
    

Erase函数

  • 和k模型的一模一样,不做赘述

    bool Erase(const K& key)
    {
    if (_root == nullptr)
    return false;

     Node* cur = _root;
     Node* parent = nullptr;
    
     while (cur)
     {
      if (cur->_key == key)
       break;
    
      parent = cur;
      if (key > cur->_key)
       cur = cur->_cright;
      else if (key < cur->_key)
       cur = cur->_cleft;
     }
    
     if (parent == nullptr)
     {
      if (cur->_cleft == nullptr && cur->_cright == nullptr)
      {
       delete _root;
       _root = nullptr;
      }
      else if (cur->_cleft == nullptr)
       _root = _root->_cright;
      else
       _root = _root->_cleft;
      return true;
     }
    
     if (cur->_cleft == nullptr && cur->_cright == nullptr)
     {
      if (cur == parent->_cleft)
       parent->_cleft = nullptr;
      else
       parent->_cright = nullptr;
    
      delete cur;
     }
     else if (cur->_cleft == nullptr)
     {
      if (cur == parent->_cleft)
       parent->_cleft = cur->_cright;
      else
       parent->_cright = cur->_cright;
    
      delete cur;
     }
     else if (cur->_cright == nullptr)
     {
      if (cur == parent->_cleft)
       parent->_cleft = cur->_cleft;
      else
       parent->_cright = cur->_cleft;
     }
     else
     {
      Node* parntRL = nullptr;
      Node* curRL = cur->_cright;
    
      while (curRL->_cleft != nullptr)
      {
       parntRL = curRL;
       curRL = curRL->_cleft;
      }
    
      swap(curRL->_key, cur->_key);
    
      if (curRL == parntRL->_cleft)
       parntRL->_cleft = curRL->_cright;
      else
       parntRL->_cright = curRL->_cright;
      delete curRL;
     }
     return true;
    }
    
相关推荐
Yan.love4 分钟前
开发场景中Java 集合的最佳选择
java·数据结构·链表
zh路西法6 分钟前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
c++·决策树·状态模式
AC使者10 分钟前
#B1630. 数字走向4
算法
冠位观测者14 分钟前
【Leetcode 每日一题】2545. 根据第 K 场考试的分数排序
数据结构·算法·leetcode
轩辰~20 分钟前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
lxyzcm39 分钟前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
蜀黍@猿1 小时前
C/C++基础错题归纳
c++
古希腊掌管学习的神1 小时前
[搜广推]王树森推荐系统笔记——曝光过滤 & Bloom Filter
算法·推荐算法
qystca1 小时前
洛谷 P1706 全排列问题 C语言
算法
浊酒南街1 小时前
决策树(理论知识1)
算法·决策树·机器学习