// // Created by PC on 25-8-17. // #ifndef AVL_H #define AVL_H #include #include "TreeNode.h" #include #include template class AVL { private: TreeNode* root; int totalHeight; void insert(TreeNode* &r, T element); void erase(TreeNode* &r, T element); void inOrder(TreeNode* r); public: //构造函数 AVL(): root(nullptr), totalHeight(0) {} explicit AVL(TreeNode* root): root(root), totalHeight(1) {} AVL(TreeNode* root, int height): root(root), totalHeight(height) {} AVL(const AVL &other) {/*深拷贝*/} ~AVL() { dispose(root); root = nullptr; } //返回 int getTotalHeight() const { return totalHeight; } int getHeight(TreeNode* node) const { return node ? node->height : 0; } int getBalance(TreeNode* node) const { return getHeight(node->left) - getHeight(node->right); } TreeNode* getRoot() { return root; } //4种旋转,关注返回值(递归) TreeNode* LL(TreeNode* &node); TreeNode* RR(TreeNode* &node); TreeNode* LR(TreeNode* &node); TreeNode* RL(TreeNode* &node); //中序遍历//删除节点 void display() { std::cout << "Root is: " << root->element << std::endl; inOrder(root); std::cout << std::endl; } void dispose(TreeNode* r); //功能 void insert(T element); void erase(T element); void outputTree(int n); }; template TreeNode * AVL::LL(TreeNode *&node) { TreeNode* left = node->left; TreeNode* right = left->right; node->left = right; left->right = node; //调整高度,已更新 node->height = std::max(getHeight(node->right), getHeight(node->left)) + 1; left->height = std::max(getHeight(left->left), getHeight(left->right)) + 1; return left; } template TreeNode* AVL::RR(TreeNode *&node) { TreeNode* right = node->right; TreeNode* left = right->left; right->left = node; node->right = left; //调整高度 node->height = std::max(getHeight(node->right), getHeight(node->left)) + 1; right->height = std::max(getHeight(right->left), getHeight(right->right)) +1; return right; } template TreeNode * AVL::LR(TreeNode *&node) { node->left = RR(node->left); node = LL(node); //不用再调整高度,组合技 return node; } template TreeNode * AVL::RL(TreeNode *&node) { node->right = LL(node->right); node = RR(node); return node; } template void AVL::inOrder(TreeNode *r) { if (r != nullptr) { inOrder(r->left); std::cout << r->element << " "; inOrder(r->right); } } template void AVL::dispose(TreeNode *r) { if (r != nullptr) { dispose(r->left); dispose(r->right); delete r; } } template void AVL::insert(T element) { insert(root, element); } template void AVL::erase(T element) { erase(root, element); } //n是输入的max template void AVL::outputTree(int n) { int index = 0; std::deque *> q; q.push_back(root); while (true) { if (q[index] != nullptr && q[index]->element == n) {break;} if (q[index]->left) q.push_back(q[index]->left); if (q[index]->right) q.push_back(q[index]->right); index++; } int cnt = 1; int jmp = 1; for (int i = 0; i <= index; i++) { cnt--; q[i] != nullptr ? std::cout << q[i]->element << " " : std::cout << "-1" << " "; if (cnt == 0) { jmp *= 2; cnt = jmp; std::cout << std::endl; } } std::cout << std::endl; } template void AVL::insert(TreeNode* &r, T element) { //BST插入 if (r == nullptr) { r = new TreeNode(element); return ; } if (element < r->element) { insert(r->left, element); } else if (element > r->element) { insert(r->right, element); } //更新高度,注意在回溯的时候,已经更新了每个父节点的height,不需要再调整(中序遍历一遍) r->height = std::max(getHeight(r->left), getHeight(r->right)) + 1; //旋转-关注四个条件 int balance = getBalance(r); if (balance > 1 && element < r->left->element) { //LL r = LL(r); } else if (balance < -1 && element > r->right->element) { //RR r = RR(r); } else if (balance > 1 && element > r->left->element) { //LR r->left = RR(r->left); r = LL(r); } else if (balance < -1 && element < r->right->element) { //RL r->right = LL(r->right); r = RR(r); } } template void AVL::erase(TreeNode *&r, T element) { /* 先按照二叉搜索树的规则删除节点:若删除节点没有孩子 → 直接删除 。 若只有一个孩子 → 让孩子接替它 。 若有两个孩子 → 找 中序后继(右子树最小) 或 中序前驱(左子树最大),替换值,再递归删除. */ if (r == nullptr) { return; } TreeNode *tmp = r; if (element < r->element) { erase(r->left, element); } else if (element > r->element) { erase(r->right, element); } else { //p = 0 or 1 if (r->left == nullptr || r->right == nullptr) { tmp = r->left ? r->left : r->right; if (!tmp) { tmp = r; r = nullptr; } else { *r = *tmp; } delete tmp; } //p = 2 else if (r->left != nullptr && r->right != nullptr) { //right-min或left-max,提到最上 TreeNode *min = r->right; while (min->left != nullptr) { min = min->left; } r->element = min->element; erase(r->right, min->element); } } if (!r) return; //这里再对每个节点进行操作,旋转;回溯的时候会将父/祖父节点都旋转 //更新高度 r->height = std::max(getHeight(r->left), getHeight(r->right)) + 1; //检查左右孩子 int balance = getBalance(r); //关注和insert的区别 if (balance > 1 && getBalance(r->left) >= 0) { //LL r = LL(r); } else if (balance < -1 && getBalance(r->right) <= 0) { //RR r = RR(r); } else if (balance > 1 && getBalance(r->left) < 0) { //LR r->left = RR(r->left); r = LL(r); } else if (balance < -1 && getBalance(r->right) > 0) { //RL r->right = LL(r->right); r = RR(r); } } #endif //AVL_H