强撸AVL(C++实现

勉强算CLRS的课后题,就贴在这了

想不到勉强看懂了算法导论红黑树代码和证明后撸个AVL看别人的代码(有错)都要撸6小时(算上简单的调试),贴代码,不想解释原理,欢迎怼错=

AvlTree.h

  1 #pragma once
  2 #include <algorithm>
  3 #include <iostream>
  4 //智能指针了解一下,这样就不用自己去delete了
  5 template<class T>
  6 struct Atnode {
  7     Atnode(T value, int height, Atnode* l, Atnode* r) :
  8         key(value), height(height), left(l), right(r){}
  9 
 10     T key;
 11     int height;
 12     Atnode* left;
 13     Atnode* right;
 14 };
 15 
 16 template<class T>
 17 class AvlTree {
 18     friend void print(AvlTree<T>* tree)//非成员函数不能加const修饰符
 19     {
 20         if (tree->Root)tree->_print(tree->Root);
 21     }
 22 public:
 23     AvlTree():Root(nullptr){}
 24     ~AvlTree() { destroy(); }
 25 
 26     void inorder()const;
 27 
 28     void destroy() { destroy(Root); }
 29 
 30     void insert(T key) { Root = insert(Root, key); }
 31     void remove(T key) { Root = remove(Root, key); }
 32 
 33     int height()const { return height(Root); }
 34 
 35 private:
 36     Atnode<T>* Root;
 37 
 38 private:
 39     void _print(Atnode<T>* );
 40     //void inorder(Atnode<T>*)const;
 41     void destroy(Atnode<T>*);
 42     
 43     Atnode<T>* insert(Atnode<T>*, T key);
 44     Atnode<T>* remove(Atnode<T>*, T key);
 45 
 46     Atnode<T>* maxmimun(Atnode<T>*);
 47     Atnode<T>* minimum(Atnode<T>*);
 48     
 49     Atnode<T>* leftrotate(Atnode<T>*);
 50     Atnode<T>* left_right(Atnode<T>*);
 51     Atnode<T>* rightrotate(Atnode<T>*);
 52     Atnode<T>* right_left(Atnode<T>*);
 53     //记得考虑空结点
 54     int height(Atnode<T>*)const;
 55 };
 56 template<class T>
 57 void AvlTree<T>::_print(Atnode<T>* root) {
 58     if (root->left != 0) {
 59         cout << root->left->key << "" << root->key << "的左孩子" << endl;
 60         _print(root->left);
 61     }
 62     if (root->right != 0) {
 63         cout << root->right->key << "" << root->key << "的右孩子" << endl;
 64         _print(root->right);
 65     }
 66 }
 67 
 68 template<class T>
 69 Atnode<T>* AvlTree<T>::insert(Atnode<T>* root, T key) {
 70     if (root == nullptr) {//进行插入
 71         root = new Atnode<T>(key, 0, 0, 0);
 72         return root;
 73     }
 74 
 75     if (root->key == key) {//插入失败
 76         std::cerr << "已存在该节点,默认不进行操作" << endl;
 77         return root;
 78     }
 79 
 80     if (root->key > key) {//递归插入左子树
 81         root->left = insert(root->left, key);
 82         if (height(root->left) - height(root->right) == 2) {
 83             if (height(root->left->right) > height(root->left->left))
 84                 root = left_right(root);
 85             else
 86                 root = rightrotate(root);
 87         }
 88     }
 89     else{
 90         root->right = insert(root->right, key);
 91         if (height(root->right) - height(root->left) == 2) {
 92             if (height(root->right->left) > height(root->right->right))
 93                 root = right_left(root);
 94             else
 95                 root = leftrotate(root);
 96         }
 97     }
 98     root->height = max(height(root->left), height(root->right)) + 1;
 99     return root;
100 }
101 
102 template<class T>
103 void AvlTree<T>::destroy(Atnode<T>* root) {
104     if (root == nullptr)return;
105     destroy(root->left);
106     destroy(root->right);
107     delete root;
108 }
109 
110 template<class T>
111 Atnode<T>* AvlTree<T>::right_left(Atnode<T>* root) {
112     root->right = rightrotate(root->right);
113     return leftrotate(root);
114 }
115 
116 template<class T>
117 Atnode<T>* AvlTree<T>::left_right(Atnode<T>* root) {
118     root->left = leftrotate(root->left);
119     return rightrotate(root);
120 }
121 
122 template<class T>
123 Atnode<T>* AvlTree<T>::leftrotate(Atnode<T>* root) {
124     Atnode<T>* rc = root->right;
125     root->right = rc->left;
126     rc->left = root;
127     root->height = std::max(height(root->left), height(root->right)) + 1;
128     rc->height = std::max(root->height, height(rc->right)) + 1;
129 
130     return rc;
131 }
132 
133 template<class T>
134 Atnode<T>* AvlTree<T>::rightrotate(Atnode<T>* root) {
135     Atnode<T>* lc = root->left;
136     root->left = lc->right;
137     lc->right = root;
138     //更新原根和新根的高度
139     root->height = std::max(height(root->left), height(root->right)) + 1;
140     lc->height = std::max(height(lc->left), root->height) + 1;
141 
142     return lc;
143 }
144 
145 template<class T>
146 Atnode<T>* AvlTree<T>::minimum(Atnode<T>*root) {
147     if (root == nullptr)return 0;
148     while (root->left)root = root->left;
149     return root;
150 }
151 
152 template<class T>
153 Atnode<T>* AvlTree<T>::maxmimun(Atnode<T>* root) {
154     if (root == nullptr)return 0;
155     while (root->right)root = root->right;
156     return root;
157 }
158 
159 
160 template<class T>
161 inline
162 int AvlTree<T>::height(Atnode<T>* n)const {
163     if (n == nullptr)return -1;
164     else return n->height;
165 }
166 
167 template<class T>
168 Atnode<T>* AvlTree<T>::remove(Atnode<T>* root, T key) {
169     if (root == 0) {
170         std::cerr << "兄弟,没得删" << endl;
171         return nullptr;
172     }
173 
174     //删除节点在左子树
175     if (key < root->key) {
176         root->left = remove(root->left, key);
177 
178         //在左子树删除后可能导致右子树高度过高,相当于在右子树插入新节点
179         if (height(root->right) - height(root->left) == 2) {
180             if (height(root->right->right) < height(root->right->left))
181                 root = right_left(root);
182             else//else分支实际上包括两种情况
183                 root = leftrotate(root);
184         }
185     }
186     //删除节点在右子树
187     else if (key > root->key) {//调用旋转函数记得巴返回值赋给原来的root
188         root->right = remove(root->right, key);//删除后拼接
189 
190         if (height(root->left) - height(root->right) == 2) {
191             if (height(root->left->right) > height(root->left->left))
192                 root = left_right(root);
193             else
194                 root = rightrotate(root);
195         }
196     }
197     else {//找到删除节点
198         if (root->left == 0) { 
199             auto deleted = root;
200             root = root->right;
201             delete deleted;
202         }
203         else if (root->right == 0) { 
204             auto deleted = root;
205             root = root->left;
206             delete deleted;
207         }
208         else {//均不为空,寻找替代root的点,
209             //可以说左子树的max,也可以是右子树的min
210             auto replace = root;
211             //在左子树找替代点
212             if (height(root->right) < height(root->left)) {
213                 replace = maxmimun(root->left);
214 
215                 if (replace == root->left) {
216                     auto deleted = root;
217                     root->left->right = root->right;
218                     root = root->left;
219                     delete deleted;
220                 }
221                 else {
222                     root->key = replace->key;
223                     root->left = remove(root->left, replace->key);
224                 }
225             }
226             else {//在右子树寻找替代点
227                 replace = minimum(root->right);
228                 if (replace == root->right) {
229                     auto deleted = root;
230                     root->right->left = root->left;
231                     root = root->right;
232                     delete deleted;
233                 }
234                 else {
235                     root->key = replace->key;
236                     root->right = remove(root->right, replace->key);
237                 }
238             }
239         }
240         //return root;
241     }//切记更新高度,由于递归,自底向上更新,美妙
242     if(root)//当节点为NULL时不要更新--
243         root->height = max(height(root->left), height(root->right)) + 1;
244     return root;
245 }

AvlTreeTest.cpp

 1 #include "AvlTree.h"
 2 
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 int main(void) {
 8     AvlTree<int> xixi;
 9     xixi.insert(3);
10     xixi.insert(2);
11     //xixi.insert(6);
12     //xixi.insert(4);
13     xixi.insert(5);
14     xixi.insert(4);
15 
16     print(&xixi);
17     xixi.remove(2);
18     print(&xixi);
19 
20     return 0;
21 }

只做了几组简单的测试,发现的小问题都改了,当然可能还有错,望告知,虚心接受批评(逃

posted on 2018-03-24 16:13  只是个回忆录  阅读(1870)  评论(0编辑  收藏  举报

导航