一.AVLTree的性質
1.左子樹和右子樹的高度差不超過1
2.左右子樹都是AVL樹
3.每一個節點都有一個平衡因子,任一點的平衡銀子爲(-1,0,1)
二.AVL樹的效率
log2n
三.AVLTreeNode
template<class K,class V> struct AVLTreeNode { AVLTreeNode<K, V>* _parent; AVLTreeNode<K, V>* _left; AVLTreeNode<K, V>* _right; K _key; V _value; int _bf; AVLTreeNode(const K& key = K(), const V& value = V()) :_parent(NULL) , _left(NULL) , _right(NULL) , _key(key) , _value(value) , _bf(0) {} };
四.Insert接口
bool Insert(const K& key,const V& value) { if (_root == NULL) //沒有節點 { _root = new Node(key, value); return true; } Node* cur = _root; Node* parent = NULL; while (cur) //找位置 { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else { break; } } Node* tmp = NULL; if (parent->_key < key) //插入節點 { tmp = new Node(key, value); parent->_right = tmp; tmp->_parent = parent; } else { tmp = new Node(key, value); parent->_left = tmp; tmp->_parent = parent; } bool isRotate = false; cur = tmp; parent = cur->_parent; while (parent) //調節平衡因子 { if (parent->_left == cur) { parent->_bf--; } else { parent->_bf++; } if (parent->_bf == 0) { break; } else if (parent->_bf == -1 || parent->_bf == 1) { cur = parent; parent = cur->_parent; } else //paernt->_bf == 2 || parent->_bf == -2 { if (parent->_bf == 2) { if (cur->_bf == 1) { _RotateL(parent); } else { _RotateRL(parent); } } else //parent->_bf == -2 { if (cur->_bf == -1) { _RotateR(parent); } else { _RotateLR(parent); } } isRotate = true; break; } } if (isRotate) //調整完需要將調整部分給上面的parent { Node* ppNode = parent->_parent; if (ppNode == NULL) { _root = parent; } else if (ppNode->_key > parent->_key) { ppNode->_left = parent; } else { ppNode->_right = parent; } } }
五.旋轉
1.左旋
void _RotateL(Node*& parent) { Node* subR = parent->_right; Node* subRleft = subR->_left; parent->_right = subRleft; if (subRleft) { subRleft->_parent = parent; } subR->_left = parent; subR->_parent = parent->_parent; parent->_parent = subR; parent->_bf = 0; subR->_bf = 0; parent = subR; }
2.右旋
void _RotateR(Node*& parent) { Node* subL = parent->_left; Node* SubLright = subL->_right; parent->_left = SubLright; if (SubLright) { SubLright->_parent = parent; } subL->_right = parent; subL->_parent = parent->_parent; parent->_parent = subL; parent->_bf = 0; subL->_bf = 0; parent = subL; }
3.左右雙旋
void _RotateLR(Node*& parent) { Node* pNode = parent; Node* subRNode = parent->_right; Node* subRLNode = subRNode->_left; int bf = subRLNode->_bf; _RotateL(parent->_left); _RotateR(parent); if (bf == -1) { subRNode->_bf = 0; pNode = -1; } else if (bf == 1) { subRNode->_bf = 1; pNode = 0; } else { subRNode->_bf = 0; pNode->_bf = 0; } }
4.右左雙旋
void _RotateRL(Node*& parent) { Node* pNode = parent; Node* subLNode = parent->_left; Node* subLRNode = subLNode->_right; int bf = subLRNode->_bf; _RotateR(parent->_right); _RotateL(parent); if (bf == -1) //特殊處理平衡因子 { subLNode->_bf = 0; pNode->_bf = 1; } else if (bf == 1) { subLNode->_bf = -1; pNode->_bf = 0; } else { subLNode->_bf = 0; pNode->_bf = 0; } }
六.代碼實現
#pragma once #include<iostream> using namespace std; template<class K,class V> struct AVLTreeNode { AVLTreeNode<K, V>* _parent; AVLTreeNode<K, V>* _left; AVLTreeNode<K, V>* _right; K _key; V _value; int _bf; AVLTreeNode(const K& key = K(), const V& value = V()) :_parent(NULL) , _left(NULL) , _right(NULL) , _key(key) , _value(value) , _bf(0) {} }; template<class K,class V> class AVLTree { typedef AVLTreeNode<K, V> Node; public: AVLTree() :_root(NULL) {} bool Insert(const K& key,const V& value) { if (_root == NULL) { _root = new Node(key, value); return true; } Node* cur = _root; Node* parent = NULL; while (cur) { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else { break; } } Node* tmp = NULL; if (parent->_key < key) { tmp = new Node(key, value); parent->_right = tmp; tmp->_parent = parent; } else { tmp = new Node(key, value); parent->_left = tmp; tmp->_parent = parent; } bool isRotate = false; cur = tmp; parent = cur->_parent; while (parent) { if (parent->_left == cur) { parent->_bf--; } else { parent->_bf++; } if (parent->_bf == 0) { break; } else if (parent->_bf == -1 || parent->_bf == 1) { cur = parent; parent = cur->_parent; } else //paernt->_bf == 2 || parent->_bf == -2 { if (parent->_bf == 2) { if (cur->_bf == 1) { _RotateL(parent); } else { _RotateRL(parent); } } else //parent->_bf == -2 { if (cur->_bf == -1) { _RotateR(parent); } else { _RotateLR(parent); } } isRotate = true; break; } } if (isRotate) { Node* ppNode = parent->_parent; if (ppNode == NULL) { _root = parent; } else if (ppNode->_key > parent->_key) { ppNode->_left = parent; } else { ppNode->_right = parent; } } } Node* Find(const K& key); void Romove(const K& key); void LevelOrder() { return _LevelOrder(_root); cout << endl; } bool Isbalance()//判斷是否爲AVLTree { return _Isbalance(_root); } protected: void _RotateL(Node*& parent) { Node* subR = parent->_right; Node* subRleft = subR->_left; parent->_right = subRleft; if (subRleft) { subRleft->_parent = parent; } subR->_left = parent; subR->_parent = parent->_parent; parent->_parent = subR; parent->_bf = 0; subR->_bf = 0; parent = subR; } void _RotateR(Node*& parent) { Node* subL = parent->_left; Node* SubLright = subL->_right; parent->_left = SubLright; if (SubLright) { SubLright->_parent = parent; } subL->_right = parent; subL->_parent = parent->_parent; parent->_parent = subL; parent->_bf = 0; subL->_bf = 0; parent = subL; } void _RotateRL(Node*& parent) { Node* pNode = parent; Node* subLNode = parent->_left; Node* subLRNode = subLNode->_right; int bf = subLRNode->_bf; _RotateR(parent->_right); _RotateL(parent); if (bf == -1) { subLNode->_bf = 0; pNode->_bf = 1; } else if (bf == 1) { subLNode->_bf = -1; pNode->_bf = 0; } else { subLNode->_bf = 0; pNode->_bf = 0; } } void _RotateLR(Node*& parent) { Node* pNode = parent; Node* subRNode = parent->_right; Node* subRLNode = subRNode->_left; int bf = subRLNode->_bf; _RotateL(parent->_left); _RotateR(parent); if (bf == -1) { subRNode->_bf = 0; pNode = -1; } else if (bf == 1) { subRNode->_bf = 1; pNode = 0; } else { subRNode->_bf = 0; pNode->_bf = 0; } } void _LevelOrder(Node* root) { if (root == NULL) return; _LevelOrder(root->_left); cout << root->_key << " "; _LevelOrder(root->_right); } int _Height(Node* root) //計算高度 { if (root == NULL) return 0; int left = _Height(root->_left); int right = _Height(root->_right); return left > right ? left + 1 : right + 1; } bool _Isbalance(Node* root) { if (root == NULL) return true; int bf = _Height(root->_left) - _Height(root->_right); if (bf != root->_bf) { cout << "error!" << root->_key << " "; } return (bf = root->_bf && _Isbalance(root->_left) && _Isbalance(root->_right)); } protected: Node* _root; }; void TestAVLTree() { AVLTree<int, int> at; int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 }; //int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++) { at.Insert(a[i],1); } at.LevelOrder(); cout << endl; cout << at.Isbalance() << endl; }
以上就是本人在學習過程中的一些經驗總結。當然,本人能力有限,難免會有紕漏,希望大家可以指正。