AVLTree代码

  1 #include <algorithm>
  2 #include <iterator>
  3 #pragma once
  4 #ifndef _BINARY_SEARCH_TREE_HPP_
  5 #define _BINARY_SEARCH_TREE_HPP_
  6 
  7 template<typename T, typename Cmp = std::less<T>>
  8 class BinarySearchTree{
  9 public:
 10     BinarySearchTree();
 11     BinarySearchTree(const BinarySearchTree &);
 12     BinarySearchTree(BinarySearchTree &&);
 13     ~BinarySearchTree();
 14 
 15     
 16 
 17     const T &Min() const;
 18     const T &Max() const;
 19     bool find(const T &) const;
 20     bool empty() const;
 21 
 22     void clear();
 23     void insert(const T &);
 24     void insert(T &&);
 25     void remove(const T &);
 26     unsigned size() const{ return _size; }
 27 
 28     BinarySearchTree &operator=(const BinarySearchTree &);
 29     BinarySearchTree &operator=(BinarySearchTree &&);
 30 
 31 private:
 32 public:
 33     struct BinaryNode{
 34         T data;
 35         BinaryNode *left;
 36         BinaryNode *right;
 37         int height;
 38         BinaryNode(const T &data, BinaryNode *lc, BinaryNode *rc, int height = 0)
 39             : data(data), left(lc), right(rc), height(0){ }
 40         BinaryNode(T &&data, BinaryNode *lc, BinaryNode *rc, int height = 0)
 41             : data(std::move(data)), left(lc), right(rc), height(0){ }
 42     };
 43 
 44 
 45     /*struct BinaryNode{
 46         using AvlNode = BinaryNode;
 47         T data;
 48         AvlNode *left;
 49         AvlNode *right;
 50         int height;
 51         AvlNode(const T &data, AvlNode *lc, AvlNode *rc, int h = 0)
 52             : data(data), left(lc), right(rc){ }
 53         AvlNode(T &&data, AvlNode *lc, AvlNode *rc, int h = 0)
 54             : data(std::move(data)), left(lc), right(rc){ }
 55     };*/
 56     BinaryNode *root;
 57     static const int ALLOWED_IMBALANCE = 1;
 58 protected:
 59     Cmp cmp;
 60     unsigned int _size;
 61 
 62     void insert(const T &, BinaryNode *&);
 63     void insert(T &&, BinaryNode *&);
 64     void remove(const T &, BinaryNode *&);
 65     BinaryNode *Min(BinaryNode *) const;
 66     BinaryNode *Max(BinaryNode *) const;
 67     bool find(const T &, BinaryNode *) const;
 68     void clear(BinaryNode *&);
 69     BinaryNode *clone(BinaryNode *) const;
 70     int height(BinaryNode *r) const;
 71     void rotateWithLeftChild(BinaryNode *&k2);
 72     void rotateWithRightChild(BinaryNode *&k1);
 73     void doubleWithLeftChild(BinaryNode *&k3);
 74     void doubleWithRightChild(BinaryNode *&k3);
 75     void balance(BinaryNode *&r);
 76 
 77 public:
 78     auto Ptr() const -> decltype(this->root){
 79         return root;
 80     }
 81 
 82 };
 83 
 84 
 85 
 86 template<typename T, typename Cmp>
 87 inline BinarySearchTree<T, Cmp>::BinarySearchTree() : root{nullptr}, _size{0}{ }
 88 
 89 template<typename T, typename Cmp>
 90 BinarySearchTree<T, Cmp>::BinarySearchTree(const BinarySearchTree &rhs) : root{nullptr}{
 91     root = clone(rhs.root);
 92     _size = rhs._size;
 93 }
 94 
 95 template<typename T, typename Cmp>
 96 BinarySearchTree<T, Cmp>::BinarySearchTree(BinarySearchTree &&rhs) : root{nullptr}{
 97     root = rhs.root;
 98     _size = rhs._size;
 99     rhs.root = nullptr;
100 }
101 
102 template<typename T, typename Cmp>
103 BinarySearchTree<T, Cmp>::~BinarySearchTree(){ 
104     clear();
105 }
106 
107 template<typename T, typename Cmp>
108 const T &BinarySearchTree<T, Cmp>::Min() const{
109     return min(root)->data;
110 }
111 
112 template<typename T, typename Cmp>
113 const T &BinarySearchTree<T, Cmp>::Max() const{
114     return max(root)->data;
115 }
116 
117 template<typename T, typename Cmp>
118 bool BinarySearchTree<T, Cmp>::find(const T &x) const{
119     return find(x, root);
120 }
121 
122 template<typename T, typename Cmp>
123 inline bool BinarySearchTree<T, Cmp>::empty() const{
124     return root == nullptr;
125 }
126 
127 template<typename T, typename Cmp>
128 inline void BinarySearchTree<T, Cmp>::clear(){ 
129     clear(root);
130 }
131 
132 template<typename T, typename Cmp>
133 void BinarySearchTree<T, Cmp>::insert(const T &x){ 
134     insert(x, root);
135 }
136 
137 template<typename T, typename Cmp>
138 void BinarySearchTree<T, Cmp>::insert(T &&x){ 
139     insert(std::move(x), root);
140 }
141 
142 template<typename T, typename Cmp>
143 void BinarySearchTree<T, Cmp>::remove(const T &x){ 
144     remove(x, root);
145 }
146 
147 template<typename T, typename Cmp>
148 BinarySearchTree<T, Cmp> &BinarySearchTree<T, Cmp>::operator=(const BinarySearchTree &rhs){
149     root = clone(rhs.root);
150     _size = rhs._size;
151 }
152 
153 template<typename T, typename Cmp>
154 BinarySearchTree<T, Cmp> &BinarySearchTree<T, Cmp>::operator=(BinarySearchTree &&rhs){
155     root = rhs.root;
156     _size = rhs._size;
157     rhs.root = nullptr;
158 }
159 
160 template<typename T, typename Cmp>
161 void BinarySearchTree<T, Cmp>::insert(const T &x, BinaryNode *&r){ 
162     if(r == nullptr){
163         r = new BinaryNode{x, nullptr, nullptr};
164         ++_size;
165     }
166     else if(cmp(x, r->data))
167         insert(x, r->left);
168     else if(cmp(r->data, x))
169         insert(x, r->right);
170     else//unique
171         ;    
172     balance(r);
173 }
174 
175 template<typename T, typename Cmp>
176 void BinarySearchTree<T, Cmp>::insert(T &&x, BinaryNode *&r){ 
177     if(r == nullptr){
178         r = new BinaryNode{std::move(x), nullptr, nullptr};
179         ++_size;
180     }
181     else if(cmp(x, r->data))
182         insert(std::move(x), r->left);
183     else if(cmp(r->data, x))
184         insert(std::move(x), r->right);
185     else
186         ;
187     balance(r);
188 }
189 
190 template<typename T, typename Cmp>
191 void BinarySearchTree<T, Cmp>::remove(const T &x, BinaryNode *&r){ 
192     if(r == nullptr)
193         return;
194     if(cmp(x, r->data))
195         remove(x, r->left);
196     else if(cmp(r->data, x))
197         remove(x, r->right);
198     else if(r->left && r->right){
199         r->data = Min(r->right)->data;
200         remove(r->data, r->right);
201     }
202     else{
203         BinaryNode *old = r;
204         r = r->left != nullptr ? r->left : r->right;
205         delete old;
206         --_size;
207     }
208     balance(r);
209 }
210 
211 template<typename T, typename Cmp>
212 typename BinarySearchTree<T, Cmp>::BinaryNode *BinarySearchTree<T, Cmp>::Min(BinaryNode *r) const{
213     if(r == nullptr)
214         return nullptr;
215     if(r->left == nullptr)
216         return r;
217     return Min(r->left);
218 }
219 
220 template<typename T, typename Cmp>
221 typename BinarySearchTree<T, Cmp>::BinaryNode *BinarySearchTree<T, Cmp>::Max(BinaryNode *r) const{
222     if(r != nullptr)
223         while(r->right){
224             r = r->right;
225         }
226     return r;
227 }
228 
229 template<typename T, typename Cmp>
230 bool BinarySearchTree<T, Cmp>::find(const T &x, BinaryNode *r) const{
231     if(r == nullptr)
232         return false;
233     else if(cmp(x, r->data))
234         return find(x, r->left);
235     else if(cmp(r->data, x))
236         return find(x, r->right);
237     return true;
238 }
239 
240 template<typename T, typename Cmp>
241 void BinarySearchTree<T, Cmp>::clear(BinaryNode *&r){ 
242     if(r){
243         clear(r->left);
244         clear(r->right);
245         delete r;
246     }
247     r = nullptr;
248     _size = 0;
249 }
250 
251 template<typename T, typename Cmp>
252 typename BinarySearchTree<T, Cmp>::BinaryNode *BinarySearchTree<T, Cmp>::clone(BinaryNode *r) const{
253     if(r == nullptr)
254         return nullptr;
255     else
256         return new BinaryNode{r->data, clone(r->left), clone(r->right)};
257 }
258 
259 template<typename T, typename Cmp>
260 inline int BinarySearchTree<T, Cmp>::height(BinaryNode *r) const{
261     return r == nullptr ? -1 : r->height;
262 }
263 
264 template<typename T, typename Cmp>
265 void BinarySearchTree<T, Cmp>::rotateWithLeftChild(BinaryNode *&k2){
266         auto k1 = k2->left;
267         k2->left = k1->right;
268         k1->right = k2;
269         k2->height = std::max(height(k2->left), height(k2->right)) + 1;
270         k1->height = std::max(height(k1->left), k2->height) + 1;
271         k2 = k1;
272 }
273 template<typename T, typename Cmp>
274 void BinarySearchTree<T, Cmp>::rotateWithRightChild(BinaryNode *&k1){
275     auto k2 = k1->right;
276     k1->right = k2->left;
277     k2->left = k1;
278     k1->height = std::max(height(k1->right), height(k1->right)) + 1;
279     k2->height = std::max(height(k2->right), k1->height) + 1;
280     k1 = k2;
281 }
282 template<typename T, typename Cmp>
283 void BinarySearchTree<T, Cmp>::doubleWithLeftChild(BinaryNode *&k3){
284     rotateWithRightChild(k3->left);
285     rotateWithLeftChild(k3);
286 }
287 template<typename T, typename Cmp>
288 void BinarySearchTree<T, Cmp>::doubleWithRightChild(BinaryNode *&k3){
289     rotateWithLeftChild(k3->right);
290     rotateWithRightChild(k3);
291 }
292 template<typename T, typename Cmp>
293 void BinarySearchTree<T, Cmp>::balance(BinaryNode *&r){
294     if(r == nullptr)
295         return;
296     if(height(r->left) - height(r->right) > ALLOWED_IMBALANCE){
297         height(r->left->left) >= height(r->left->right) ? rotateWithLeftChild(r) : doubleWithLeftChild(r);
298     }
299     else if(height(r->right) - height(r->left) > ALLOWED_IMBALANCE){
300         height(r->right->right) >= height(r->right->left) ? rotateWithRightChild(r) : doubleWithRightChild(r);
301     }
302     r->height = std::max(height(r->left), height(r->right)) + 1;
303 }
304 #endif // !_BINARY_SEARCH_TREE_HPP_

猜你喜欢

转载自www.cnblogs.com/MasterYan576356467/p/11357230.html