勉强算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 }
只做了几组简单的测试,发现的小问题都改了,当然可能还有错,望告知,虚心接受批评(逃