说来惭愧,工作三年了一直都没有真正弄懂AVL树的原理。因为最近在看STL源码,但STL的map和set的底层数据结构是红黑树,而红黑树是不严格的AVL树,所以理解红黑树之前必须要先弄懂AVL树。借此契机,将AVL树从原理和代码层面拿下。
1. AVL树简介
AVL树种的任意节点的左右子树的高度差的绝对值最大为1,其本质是带了平衡功能的二叉搜索树。
二叉搜索树在数据极端情况下会退化成单链表,时间复杂度也会退化成O(n)。而AVL树定义了旋转操作,在平衡因子大于2时,通过旋转来调整树的结构,来重新满足平衡因子小于2,确保在查找、插入和删除在平均和最坏情况下都是O(logn)。
2. AVL旋转
AVL旋转是AVL树最核心的部分,需要重点掌握。在理解AVL旋转之前先知道以下几个概念:
- AVL树节点的插入总是在叶子节点;
- AVL树在插入节点之前是满足平衡条件的;
- 插入新节点后有可能满足平衡条件也可能不满足;
- 当不满足平衡条件时需要对新的树进行旋转。
旋转之前首先需要找到插入节点向上第一个不平衡的节点(记为A),新插入节点只能在A的的左子树的左子树、左子树的右子树、右子树的左子树、右子树的右子树上,对应四种不同的旋转方式。
#ifndef _AVLTREE_H #define _AVLTREE_H #include <iostream> template<typename T> class AVLNode { public: T val; AVLNode* left; AVLNode* right; AVLNode(T x) :val(x), left(NULL), right(NULL) {} }; template<typename T> class AVLTree { typedef AVLNode<T> AVLNode; private: AVLNode* avlroot; int max(int a, int b) { return a > b ? a : b; } //获取树高度 int treeHeight(const AVLNode* root) { if (root == NULL) return 0; return max(treeHeight(root->left), treeHeight(root->right)) + 1; } //计算平衡因子 int treeBalanceFector(const AVLNode* root) { if (root == NULL) return 0; return treeHeight(root->left) - treeHeight(root->right); } //向左旋转 AVLNode* rotateLeft(AVLNode* root) { AVLNode* tmp = root->right; root->right = tmp->left; tmp->left = root; return tmp; } //向右旋转 AVLNode* rotateRight(AVLNode* &root) { AVLNode* tmp = root->left; root->left = tmp->right; tmp->right = root; return tmp; } //获取最小节点 AVLNode* minNode(AVLNode* root) { if (root->left != NULL) root = root->left; return root; } //重新平衡 AVLNode* treeRebalance(AVLNode* root) { int fector = treeBalanceFector(root); if (fector > 1 && treeBalanceFector(root->left) > 0) // LL return rotateRight(root); if (fector > 1 && treeBalanceFector(root->left) <= 0) // LR { root->left = rotateLeft(root->left); return rotateRight(root); } if (fector < -1 && treeBalanceFector(root->right) <= 0) // RR return rotateLeft(root); if (fector < -1 && treeBalanceFector(root->right) > 0) // RL { root->right = rotateRight(root->right); return rotateLeft(root); } return root; } //插入节点 void treeInsert(AVLNode*& root, const T& val) { if (root == NULL) { root = new AVLNode(val); } else { if (val == root->val) return; if (val < root->val) treeInsert(root->left, val); else treeInsert(root->right, val); } root = treeRebalance(root); } //删除节点 void treeDelete(AVLNode*& root, const T& val) { if (root == NULL) return; if (val == root->val) { if (root->right != NULL){ AVLNode* min_node = minNode(root->right); root->val = min_node->val; delete min_node; } else { AVLNode* deleteNode = root; root = root->left; delete deleteNode; } } else { if (val < root->val) treeDelete(root->left, val); else treeDelete(root->right, val); } root = treeRebalance(root); } //前序遍历 void preOrderTraversal(AVLNode* root) { if (root == NULL) return; std::cout << root->val << " "; preOrderTraversal(root->left); preOrderTraversal(root->right); } //中序遍历 void midOrderTraversal(AVLNode* root) { if (root == NULL) return; midOrderTraversal(root->left); std::cout << root->val << " "; midOrderTraversal(root->right); } public: AVLTree() { avlroot = NULL; } ~AVLTree() { } void insert(const T& val) { treeInsert(avlroot, val); } void del(const T& val) { treeDelete(avlroot, val); } void preOrder() { preOrderTraversal(avlroot); } void midOrder() { midOrderTraversal(avlroot); } }; #endif // !_AVLTREE_H