zoukankan      html  css  js  c++  java
  • 二叉查找树_代码_详细注释

      1 #include <iostream>
      2 #include <ctime>
      3 using namespace std;
      4 
      5 template<typename T>
      6 struct BinaryNode
      7 {
      8     T element;
      9     BinaryNode<T> *left;
     10     BinaryNode<T> *right;
     11 
     12     BinaryNode(const T &theElement, BinaryNode *lt, BinaryNode *rt)
     13         : element(theElement), left(lt), right(rt) {}
     14 };
     15 
     16 
     17 template<typename T>
     18 class BinarySearchTree
     19 {
     20 public:
     21     BinarySearchTree() {
     22         root = nullptr;
     23     }
     24     BinarySearchTree(const BinarySearchTree& rhs) {  //复制构造函数
     25         root = clone(rhs.root);
     26     }
     27     ~BinarySearchTree();
     28 
     29     const T &findMin() const {
     30         return findMin(root)->element;
     31     }
     32     const T &findMax() const {
     33         return findMax(root)->element;
     34     }
     35     bool contains(const T& x) const;
     36     bool isEmpty() const {
     37         if (root == nullptr)
     38             return true;
     39         return false;
     40     }
     41     void printTree() const {
     42         printTree(root);
     43     }
     44 
     45     void makeEmpty();
     46     void insert(const T &x);
     47     void remove(const T &x);
     48 
     49     const BinarySearchTree& operator = (const BinarySearchTree& rhs);
     50 
     51 private:
     52 
     53     BinaryNode<T> *root;                      //指向树根结点的指针
     54 
     55     void insert(const T & x, BinaryNode<T> * & t);  
     56     void remove(const T & x, BinaryNode<T> * & t);
     57     BinaryNode<T> * findMin(BinaryNode<T> *t) const;
     58     BinaryNode<T> * findMax(BinaryNode<T> *t ) const;
     59     bool contains(const T & x, BinaryNode<T> *t) const;
     60     void makeEmpty( BinaryNode<T> * & t );
     61     void printTree( BinaryNode<T> * t ) const;
     62     BinaryNode<T> * clone( BinaryNode<T> * t ) const;
     63 };
     64 
     65 template<typename T>
     66 bool BinarySearchTree<T>::contains(const T& x) const
     67 {
     68     return contains(x, root);
     69 }
     70 
     71 template<typename T>
     72 bool BinarySearchTree<T>::contains(const T & x, BinaryNode<T> *t) const
     73 {
     74     if (t == nullptr)
     75         return false;
     76     else if (x < t->element)          // x 小, 说明应该在左边找
     77         return contains(x, t->left);
     78     else if (t->element < x)          // x 大, 说明应该在右面找
     79         return contains(x, t->right);
     80     else 
     81         return true;
     82 }
     83 
     84 //findMin--返回指向树中包含最小元的结点的指针
     85 template<typename T>
     86 BinaryNode<T> * BinarySearchTree<T>::findMin(BinaryNode<T> *t) const
     87 {
     88     if (t == nullptr)
     89         return  nullptr;
     90     if (t->left == nullptr)
     91         return t;
     92     return findMin(t->left);
     93 }
     94 
     95 template<typename T>
     96 BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T> *t) const
     97 {
     98     if (t != nullptr)
     99         while (t->right != nullptr) {
    100             t = t->right;
    101         }
    102     return t;
    103 }
    104 
    105 template<typename T>
    106 void BinarySearchTree<T>::insert(const T &x)
    107 {
    108     insert(x, root);
    109 }
    110 
    111 /************************************************************************/
    112 /* x is the item to insert        */
    113 /* t is the node that roots the subtree*/
    114 /* Set the new root of the subtree*/
    115 ///* 只有当一个新树叶生成时候,t才改变.
    116 ///* t 是到p->left或p->right的引用.==> 意味着p->left或p->right将会改变为指向新结点.
    117 /************************************************************************/
    118 template<typename T>
    119 void BinarySearchTree<T>::insert(const T & x, BinaryNode<T> * & t)
    120 {
    121     if (t == nullptr)         //没有结点,在该位置处添加新结点
    122         t = new BinaryNode<T>(x, nullptr, nullptr);
    123     else if (x < t->element)  //x 小, 在左子树查询
    124         insert(x, t->left);  
    125     else if (t->element < x)  //x 大, 在右子树查询
    126         insert(x, t->right);
    127     else;                     //Duplicate, do nothing;
    128 }
    129 
    130 template<typename T>
    131 void BinarySearchTree<T>::remove(const T &x)
    132 {
    133     remove(x, root);
    134 }
    135 
    136 ///************************************************************************/
    137 ///* x is item to remove 
    138 /////* t is the node that roots the subtree
    139 /////* Set the new root of the subtree
    140 ///* 1.结点是一片树叶时 -- 可被立即删除
    141 ///* 2.结点有一个儿子, 则该结点可以在其父节点调整他的链 以绕过该结点后被删除
    142 ///* 3.结点有两个儿子, 则其右子树的最小数据代替该结点的数据,并递归删除那个结点
    143 ///* 注: 右子树中的最小的结点不可能有左结点
    144 ///************************************************************************/
    145 template<typename T>
    146 void BinarySearchTree<T>::remove(const T &x, BinaryNode<T> * & t)
    147 {
    148     if (t == nullptr) return;     //Item not found; do nothing
    149     if (x < t->element)           //x 小,在左子树递归查找
    150         remove(x, t->left);
    151     else if (t->element < x)      //x 大,在右子树递归查找
    152         remove(x, t->right); 
    153     else if (t->left != nullptr && t->right != nullptr)  //two children
    154     {
    155         //在右子树中查找最小数据代替该结点数据.;
    156         t->element = findMin(t->right)->element;
    157         remove(t->element, t->right);                    //删除该结点
    158     }
    159     else                         //只有一个结点或是树叶. 调整它的链,以绕过该结点后被删除.
    160     {                          
    161         BinaryNode<T> *oldNode = t;
    162         t = (t->left != nullptr) ? t->left : t->right;
    163         delete oldNode;
    164     }
    165 }
    166 
    167 /************************************************************************/
    168 ///* Destructor for the tree
    169 /************************************************************************/
    170 template<typename T>
    171 BinarySearchTree<T>::~BinarySearchTree()
    172 {
    173     makeEmpty();
    174 }
    175 
    176 template<typename T>
    177 void BinarySearchTree<T>::makeEmpty()       //公有函数
    178 {
    179     makeEmpty(root);
    180 }
    181 
    182 /************************************************************************/
    183 ///* Internal method to make subtree empty -- 私有函数
    184 /************************************************************************/
    185 template<typename T>
    186 void BinarySearchTree<T>::makeEmpty(BinaryNode<T> * & t)   
    187 {
    188     if (t != nullptr)
    189     {
    190         makeEmpty(t->left);
    191         makeEmpty(t->right);
    192         delete t;
    193     }
    194     t = nullptr;
    195 }
    196 
    197 /************************************************************************/
    198 ///* Deep copy
    199 /************************************************************************/
    200 template<typename T>
    201 const BinarySearchTree<T>& BinarySearchTree<T>::operator = (const BinarySearchTree &rhs)
    202 {
    203     if (this != &rhs) {
    204         makeEmpty();
    205         root = clone(rhs.root);
    206     }
    207     return *this;
    208 }
    209 
    210 /************************************************************************/
    211 ///* Internal method to clone subtree.  --  递归复制结点
    212 /************************************************************************/
    213 template<typename T>
    214 BinaryNode<T>* BinarySearchTree<T>::clone(BinaryNode<T> * t) const
    215 {
    216     if (t == nullptr)
    217         return nullptr;
    218     return new BinaryNode<T>( t->element, clone(t->left), clone(t->right) );
    219 }
    220 
    221 /************************************************************************/
    222 ///* printTree  
    223 /************************************************************************/
    224 template<typename T>
    225 void BinarySearchTree<T>::printTree(BinaryNode<T> * t) const
    226 {
    227     
    228     if (t != nullptr) {
    229         cout << t->element << ' ';
    230         printTree(t->left);
    231         printTree(t->right);
    232     }
    233 }
    234 
    235 int main()
    236 {
    237     srand((unsigned)time(nullptr));
    238     int testData, t = 0;
    239     BinarySearchTree<int> test;
    240     cout << "输入数字个数: 
    ";
    241     cin >> t;
    242     cout << "输入数字: 
    ";
    243     while (t--)
    244     {
    245         testData = rand() % 1000 + 1;
    246         test.insert(testData);
    247     }
    248     cout << "
    全部元素为: 
    ";
    249     test.printTree();
    250     cout << "
    Max = " << test.findMax() << endl;
    251     cout << "Min = " << test.findMin() << endl;
    252     cout << "输入查找元素: 
    ";
    253     cin >> testData;
    254     cout << "是否包含 " << testData  << " : " << test.contains(testData) << endl; 
    255     test.printTree();
    256     cout << endl;
    257     cout << "输入删除元素: 
    ";
    258     cin >> testData;
    259     test.remove(testData);
    260     test.printTree();
    261     cout << endl;
    262     return 0;
    263 }
  • 相关阅读:
    P4559 [JSOI2018]列队
    2019.2.14 考试T3 交互题
    2019.2.14 考试T1 FFT
    P3240 [HNOI2015]实验比较 树形DP
    bzoj 3514: Codechef MARCH14 GERALD07加强版 LCT+主席树
    P4172 [WC2006]水管局长 LCT维护最小生成树
    P4177 [CEOI2008]order 最小割
    CF1073G Yet Another LCP Problem SA+权值线段树
    CF1110D Jongmah
    2019.2.10考试T2, 多项式求exp+生成函数
  • 原文地址:https://www.cnblogs.com/douzujun/p/5990205.html
Copyright © 2011-2022 走看看