zoukankan      html  css  js  c++  java
  • 二叉搜索树的实现

    这次贴上二叉搜索树的实现,搜索插入删除我都实现了递归和非递归两种版本(递归函数后面有_R标识)

      1 #pragma once
      2 #include<iostream>
      3 using namespace std;
      4 
      5 
      6 template<class K,class V>
      7 struct BSTNode
      8 {
      9     K _key;
     10     V _value;
     11     BSTNode *_left;
     12     BSTNode *_right;
     13     BSTNode(const K& key, const V& value)
     14         :_key(key)
     15         ,_value(value)
     16         ,_left(NULL)
     17         ,_right(NULL)
     18     {
     19     }
     20 };
     21 
     22 
     23 
     24 
     25 
     26 
     27 template<class K,class V>
     28 class BSTree
     29 {
     30     typedef BSTNode<K, V> Node;
     31 public:
     32     BSTree()
     33         :_root(NULL)
     34     {
     35 
     36     }
     37     ~BSTree()
     38     {}
     39     bool Insert(const K& key,const V& value)
     40     {
     41         if (_root == NULL)
     42         {
     43             _root = new Node(key, value);
     44         }
     45         Node *cur = _root;
     46         Node *parent = _root;
     47         while (cur)
     48         {
     49             parent = cur;
     50             if (cur->_key > key)
     51             {
     52                 cur = cur->_left;
     53             }
     54             else if (cur->_key < key)
     55             {
     56                 cur = cur->_right;
     57             }
     58             else
     59             {
     60                 return false;
     61             }
     62         }
     63         if (parent->_key > key)
     64         {
     65             parent->_left = new Node(key, value);
     66         }
     67         else
     68         {
     69             parent->_right = new Node(key, value);
     70         }
     71         return true;
     72     }
     73     bool Insert_R(const K& key, const V& value)
     74     {
     75         return _Insert_R(_root,key,value);
     76     }
     77     bool Remove(const K& key)
     78     {
     79         if (_root == NULL)
     80         {
     81             return false;
     82         }
     83         if (_root->_left == NULL && _root->_right == NULL)
     84         {
     85             delete _root;
     86             _root = NULL;
     87             return true;
     88         }
     89         Node *del = _root;
     90         Node *parent = _root;
     91         while (del && del->_key != key)
     92         {
     93             parent = del;
     94             if (del->_key > key)
     95             {
     96                 del = del->_left;
     97             }
     98             else if (del->_key < key)
     99             {
    100                 del = del->_right;
    101             }
    102         }
    103         if (del)
    104         {
    105             if (del->_left == NULL || del->_right == NULL)
    106             {
    107                 if (del->_left == NULL)
    108                 {
    109                     if (parent->_left == del)
    110                     {
    111                         parent->_left = del->_right;
    112                     }
    113                     else
    114                     {
    115                         parent->_right = del->_right;
    116                     }
    117                 }
    118                 else
    119                 {
    120 
    121                     if (parent->_left == del)
    122                     {
    123                         parent->_left = del->_left;
    124                     }
    125                     else
    126                     {
    127                         parent->_right = del->_left;
    128                     }
    129                 }
    130                 delete del;
    131                 return true;
    132             }
    133             else
    134             {
    135                 Node *InOrderfirst = del->_right;
    136                 Node *parent = del;
    137                 while (InOrderfirst->_left != NULL)
    138                 {
    139                     parent = InOrderfirst;
    140                     InOrderfirst = InOrderfirst->_left;
    141                 }
    142                 swap(del->_key, InOrderfirst->_key);
    143                 swap(del->_value, InOrderfirst->_value);
    144                 if (InOrderfirst->_left == NULL)
    145                 {
    146                     if (parent->_left == InOrderfirst)
    147                     {
    148                         parent->_left = InOrderfirst->_right;
    149                     }
    150                     else
    151                     {
    152                         parent->_right = InOrderfirst->_right;
    153                     }
    154                 }
    155                 else
    156                 {
    157 
    158                     if (parent->_left == InOrderfirst)
    159                     {
    160                         parent->_left = InOrderfirst->_left;
    161                     }
    162                     else
    163                     {
    164                         parent->_right = InOrderfirst->_left;
    165                     }
    166                     
    167                 }
    168                 delete InOrderfirst;
    169                 return true;
    170             }
    171         }
    172         return false;
    173     }
    174     bool Remove_R(const K& key)
    175     {
    176         return _Remove_R(_root, key);
    177     }
    178     Node *Find(const K& key)
    179     {
    180         Node *cur = _root;
    181         while (cur)
    182         {
    183             if (cur->_key > key)
    184             {
    185                 cur = cur->_left;
    186             }
    187             else if (cur->_key < key)
    188             {
    189                 cur = cur->_right;
    190             }
    191             else
    192             {
    193                 return cur;
    194             }
    195         }
    196         return NULL;
    197     }
    198     Node *Find_R(const K& key)
    199     {
    200         return _Find_R(_root,key);
    201     }
    202     void InOrder()
    203     {
    204         return _InOrder(_root);
    205     }
    206 protected:
    207     bool _Remove_R(Node *&root,const K& key)
    208     {
    209         if (root == NULL)
    210         {
    211             return false;
    212         }
    213         if (root->_key > key)
    214         {
    215             return _Remove_R(root->_left, key);
    216         }
    217         else if (root->_key < key)
    218         {
    219             return _Remove_R(root->_right, key);
    220         }
    221         else
    222         {
    223             if (root->_left == NULL || root->_right == NULL)
    224             {
    225                 if (root->_left == NULL)
    226                 {
    227                     Node *del = root;
    228                     root = root->_right;
    229                     delete del;
    230                     return true;
    231                 }
    232                 else
    233                 {
    234                     Node *del = root;
    235                     root = root->_left;
    236                     delete del;
    237                     return true;
    238                 }
    239             }
    240             else
    241             {
    242                 Node *InOrderfirst = root->_right;
    243                 while (InOrderfirst->_left != NULL)
    244                 {
    245                     InOrderfirst = InOrderfirst->_left;
    246                 }
    247                 swap(InOrderfirst->_key, root->_key);
    248                 swap(InOrderfirst->_value, root->_value);
    249                 return _Remove_R(root->_right, key);
    250             }
    251         }
    252     }
    253     void _InOrder(Node *root)
    254     {
    255         if (root == NULL)
    256         {
    257             return;
    258         }
    259         _InOrder(root->_left);
    260         cout << root->_key << " ";
    261         _InOrder(root->_right);
    262     }
    263     Node *_Find_R(Node *root, const K& key)
    264     {
    265         if (root == NULL)
    266         {
    267             return NULL;
    268         }
    269         if (root->_key < key)
    270         {
    271             return _Find_R(root->_right, key);
    272         }
    273         else if (root->_key > key)
    274         {
    275             return _Find_R(root->_left, key);
    276         }
    277         else
    278         {
    279             return root;
    280         }
    281     }
    282     bool _Insert_R(Node *&root, const K& key, const V& value)
    283     {
    284         if (root == NULL)
    285         {
    286             root = new Node(key, value);
    287             return true;
    288         }
    289         
    290         if (root->_key > key)
    291         {
    292             return _Insert_R(root->_left, key, value);
    293         }
    294         else if (root->_key < key)
    295         {
    296             return _Insert_R(root->_right, key, value);
    297         }
    298         else
    299         {
    300             return false;
    301         }
    302     }
    303 protected:
    304     Node *_root;
    305 };
    306 
    307 
    308 void TestBinarySearchTree()
    309 {
    310     BSTree<int, int> bst1;
    311     int a[10] = { 5,4,3,1,7,8,2,6,0,9 };
    312     for (int i = 0; i < 10; ++i)
    313     {
    314         bst1.Insert(a[i],a[i]);
    315     }
    316 //    bst1.InOrder();
    317     //cout << endl;
    318     //cout << bst1.Find(1)->_key << "  ";
    319     //cout << bst1.Find(5)->_key << "  ";
    320     //cout << bst1.Find(9)->_key << "  ";
    321     //cout << bst1.Find_R(1)->_key << "  ";
    322     //cout << bst1.Find_R(5)->_key << "  ";
    323     //cout << bst1.Find_R(9)->_key << "  ";
    324     //cout << endl;
    325     bst1.Remove_R(5);
    326     bst1.Remove_R(2);
    327     bst1.Remove_R(8);
    328     for (int i = 0; i < 10; ++i)
    329     {
    330         bst1.Remove_R(a[i]);
    331     }
    332     bst1.InOrder();
    333     bst1.Remove(5);
    334     bst1.Remove(2);
    335     bst1.Remove(8);
    336     for (int i = 0; i < 10; ++i)
    337     {
    338         bst1.Remove(a[i]);
    339     }
    340     bst1.InOrder();
    341 }
    二叉搜索树的性质:
    1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
    2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
    3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
    4. 左右子树都是二叉搜索树。

    插入步骤很简单,就是从根节点开始,进行比较,然后我那个左(右)子树走,走到叶子节点之后,链接上就可以了

    寻找也是类似插入的,很简单

    删除就要略微繁琐一点有三种情况(其实直接就可以归类为两种)

    • 被删除的节点是叶子节点(左右孩子都是空)
      • 直接删除就可以了
    • 被删除的节点只有一个孩子(左孩子或者右孩子是空)
      • 删除之前需要将父亲节点指针指向被删除节点的孩子
    • 被删除的节点左右孩子都健在(左右孩子都不为空)
      • 删除之前需要和一个特定位置的节点交换
  • 相关阅读:
    业余草双因素认证(2FA)教程
    业余草网站热门关键字
    微博爬虫“免登录”技巧详解及 Java 实现(业余草的博客)
    业余草通告CSDN博客用户zhang__ao非法转载文章的公告
    CODE大全给你推荐几个免费的leapftp 注册码
    业余草最新热门博客推荐
    莫比乌斯反演
    P5091 【模板】欧拉定理
    LaTeX Test
    P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
  • 原文地址:https://www.cnblogs.com/lenomirei/p/5394781.html
Copyright © 2011-2022 走看看