• C++ 二叉搜索树原理及其实现


    首先是概念:
    二叉搜索树又称二叉排序树,它具有以下的性质:

    • 若是左子树不为空,则左子树上所有节点的值小于根节点的值
    • 若是右子树不为空,则右子树上所有结点的值大于根节点的值
    • 二叉搜索树的左右子树也是二叉搜索树
    • 二叉搜索树的中序排列是一个有序数列

    再下来是它的实现

    首先是构造节点

     1 template<class K>
     2 struct BStreeNode{
     3     BStreeNode(const K& date = K())    //节点的定义
     4     :leftC(nullptr),    // 初始化
     5     rightC(nullptr),
     6     date_(date)
     7     {}
     8     BStreeNode<K> *leftC;      //左孩子
     9     BStreeNode<K> *rightC;    //右孩子
    10     K date_;
    11 };

    然后是类的实现(具体细节都标在了注释里):

      1 template<class K>
      2 class BStree{
      3     typedef BStreeNode<K> BsNode;
      4 public:
      5     BStree() :
      6         _root(nullptr)    
      7     {}
      8     BsNode* Find(const K& date){       //查找节点
      9         BsNode* pNode = _root;
     10         while (pNode){
     11             if (pNode->date_ == date){
     12                 return pNode;
     13             }
     14             else if (pNode->date_ > date){
     15                 pNode = pNode->rightC;
     16             }
     17             else
     18                 pNode = pNode->leftC;
     19         }
     20         return nullptr;
     21     }
     22     bool Insert(const K& date){
     23         BsNode *pNode = _root;
     24         BsNode *parent=nullptr;
     25         if (_root == nullptr){      //空树时开辟空间定义为根节点
     26             _root = new BsNode(date);
     27             return true;
     28         }
     29         else if (Find(date)){   //存在相同结点不进行插入
     30             return false;
     31         }
     32         else{
     33             while (pNode){         //找到插入位置,但是这里循环结束后只确认了父母结点,是做左孩子还是右孩子不确认( 因为此时值为nullptr )
     34                 parent = pNode;
     35                 if (pNode->date_ > date){
     36                     pNode = pNode->leftC;
     37                 }
     38                 else{
     39                     pNode = pNode->rightC;
     40                 }
     41             }
     42             pNode = new BsNode(date);    //构造结点
     43             if (parent->date_ > date){       //确认是做左孩子还是右孩子
     44                 parent->leftC = pNode;
     45             }
     46             else{
     47                 parent->rightC = pNode;
     48             }
     49             return true;
     50         }
     51     }
     52 
     53     bool Delete(const K& date){
     54         BsNode *pNode = _root;
     55         BsNode *parent = nullptr;
     56         if (pNode == nullptr){    //空树情况
     57             return false;
     58         }
     59         while (pNode){      //找到要删除的结点
     60             if (pNode->date_ == date){
     61                 break;
     62             }
     63             else if (pNode->date_ < date){
     64                 parent = pNode;
     65                 pNode = pNode->rightC;
     66             }
     67             else{
     68                 parent = pNode;
     69                 pNode = pNode->leftC;
     70             }
     71         }
     72         //BsNode *pdel=pNode;
     73         if (pNode == parent){      //要删除的点是根节点
     74             if (pNode->leftC){
     75                 pNode = pNode->leftC;
     76             }
     77             else if (pNode->rightC){
     78                 pNode = pNode->rightC;
     79             }
     80             else{
     81                 pNode = nullptr;
     82             }
     83         }
     84         if (pNode == nullptr){   // 没有找到要删除的节点
     85             return false;
     86         }
     87         if (pNode->rightC && pNode->leftC == nullptr){  //结点只有右子树
     88             if (pNode == parent->leftC){
     89                 parent->leftC = pNode->rightC;
     90             }
     91             else{
     92                 parent->rightC = pNode->rightC;
     93             }
     94         }
     95         else if (pNode->leftC && pNode->rightC == nullptr){   //结点只有左子树
     96             if (pNode == parent->leftC){
     97                 parent->leftC = pNode->leftC;
     98             }
     99             else{
    100                 parent->rightC = pNode->leftC;
    101             }
    102         }
    103         else if (pNode->leftC && pNode->rightC){    //儿女俱全
    104             if (pNode == parent->leftC){   //要删除的节点是父母节点的左孩子,删除后的位置要由原先节点的右孩子替代
    105                 pNode->rightC->leftC = pNode->leftC;
    106                 parent->leftC = pNode->rightC;
    107             }
    108             else{
    109                 pNode->leftC->rightC= pNode->rightC;  //要删除的节点是父母节点的右孩子,删除后的位置要由原先节点的左孩子替代
    110                 parent->rightC = pNode->leftC;
    111             }
    112         }
    113         else{                                        //无子可依
    114             if (pNode == parent->leftC){
    115                 parent->leftC = nullptr;
    116             }
    117             else{
    118                 parent->rightC = nullptr;
    119             }
    120         }
    121         delete pNode;     //在连接完成后最后再进行删除
    122         return true;
    123     }
    124 
    125     BsNode* IfLeftMost(){
    126         if (_root == nullptr){
    127             return nullptr;
    128         }
    129         BsNode *pNode = _root;
    130         while (pNode->leftC){
    131             pNode = pNode->leftC;
    132         }
    133         return pNode;
    134     }
    135     BsNode* IfRightMost(){
    136         if (_root == nullptr){
    137             return nullptr;
    138         }
    139         BsNode *pNode = _root;
    140         while (pNode->rightC){
    141             pNode = pNode->rightC;
    142         }
    143         return pNode;
    144     }
    145     void InOrder(){  //定义一个借口给外部调用,因为根节点在这里是private权限
    146         InOrder(_root);
    147         cout << endl;
    148     }
    149 
    150 private:
    151     void InOrder(BsNode *pNode){    //二叉树的中序遍历,用来检查结果(二叉搜索树中序遍历应该是一个有序序列)
    152         if (pNode){
    153             InOrder(pNode->leftC);
    154             cout << pNode->date_ << ' ';
    155             InOrder(pNode->rightC);
    156         }
    157     }
    158 private:
    159     BsNode *_root;
    160 };
  • 相关阅读:
    rpc和http的区别
    Mysql和Oracle的区别
    RabbitMQ基本概念
    如何关闭139端口及445端口等危险端口
    Vert.x入门教程之Hello World
    wordpress常用插件汇总
    wordpress上一款不错的音乐播放器-Hermit
    网易云音乐 – 插入歌单及 HTML5 播放器 WORDPRESS 插件
    WordPress如何在文章或侧边栏通过网易云音乐添加音乐播放器
    HEXO+Github,搭建属于自己的博客
  • 原文地址:https://www.cnblogs.com/Kaniso-Vok/p/12052423.html
Copyright © 2020-2023  润新知