AVL树的实现

来源:互联网 发布:教务软件哪个好 编辑:程序博客网 时间:2024/05/29 21:35

AVL树的概念:

一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:

1.它的左右子树都是AVL树

2.左子树和右子树高度之差(简称平衡因子)的绝对值不超过(-1,0,1)

如果一棵二叉搜索树是高度平衡的,它就是AVL树,如果它有n个结点,其高度可保持在O(lgn),平均搜索时间复杂度O(lg(n))。AVL在构建时,插入的每一个节点都需要满足搜索二叉树的性质,但同时也要保证左右子树的高度之差的绝对值不超过1,则AVL在构建时需要做平衡化旋转。

平衡化旋转:如果在一棵原本是平衡的二叉搜索树中插入一个新节点,可能造成不平衡,此时必须调整树的结构,使之平衡化。如下图,是四种平衡化旋转的情况:


下面我们来看代码的实现:

#include<iostream>using namespace std;template<class K,class V>struct AVLTreeNode{AVLTreeNode(const K& key, const V& value):_key(key), _value(value), _pleft(NULL), _pright(NULL), _pParent(NULL), _bf(0){}AVLTreeNode<K, V>* _pleft;AVLTreeNode<K, V>* _pright;AVLTreeNode<K, V>* _pParent;K _key;V _value;int _bf;};template<class K,class V>class AVLTree{typedef AVLTreeNode<K, V> Node;public:AVLTree():_pRoot(NULL){}~AVLTree(){}bool Insert(const K& key, const V& value){return _Insert(key, value);}void InOrder(){_InOrder(_pRoot);cout << endl;}size_t Height(){return _Height(_pRoot);}bool IsBalanceTree(){return IsBalanceTree(_pRoot);}bool Remove(const K& key){return _Remove(key,_pRoot);}Node* firstInOrder(Node*& node){return _firstInOrder(node);}protected:bool _Insert(const K& key, const V& value){if (_pRoot == NULL){_pRoot = new Node(key, value);return true;}Node* pCur = _pRoot;Node* pParent = NULL;while (pCur){if (key < pCur->_key){pParent = pCur;pCur = pCur->_pleft;}else if (key > pCur->_key){pParent = pCur;pCur = pCur->_pright;}else{return false;}}pCur = new Node(key, value);if (key < pParent->_key){pParent->_pleft = pCur;pCur->_pParent = pParent;}else{pParent->_pright = pCur;pCur->_pParent= pParent;}while (pParent){if (pParent->_pright == pCur)pParent->_bf++;elsepParent->_bf--;if (pParent->_bf == 1 || pParent->_bf == -1){pCur = pParent;pParent = pCur->_pParent;}else if (pParent->_bf == 0){break;}else{if (pParent->_bf == 2){Node* pSubR = pParent->_pright;if (pSubR->_bf == 1)_RotateL(pParent);else_RotateRL(pParent);}else{Node* pSubL = pParent->_pleft;if (pSubL->_bf == -1)_RotateR(pParent);else{_RotateLR(pParent);}}break;}}return true;}void _RotateL(Node*& pParent){Node* pSubR = pParent->_pright;Node* pSubRL = pSubR->_pleft;pParent->_pright = pSubRL;if (pSubRL){pSubRL->_pParent = pParent;}pSubR->_pleft = pParent;Node* pPParent = pParent->_pParent;pParent->_pParent = pSubR;if (NULL == pPParent)_pRoot = pSubR;else{if (pPParent->_pleft == pParent)pPParent->_pleft = pSubR;elsepPParent->_pright = pSubR;}pSubR->_pParent = pPParent;pParent->_bf = pSubR->_bf = 0;}void _RotateR(Node*& pParent){Node* pSubL = pParent->_pleft;Node* pSubLR = pSubL->_pright;pParent->_pleft = pSubLR;if (pSubLR){pParent->_pright = pSubLR;}pSubL->_pright = pParent;Node* pPParent = pParent->_pParent;pParent->_pParent = pSubL;if (NULL == pPParent)_pRoot = pSubL;else{if (pPParent->_pleft == pParent)pPParent->_pleft = pSubL;elsepPParent->_pright = pSubL;}pSubL->_pParent = pPParent;pParent->_bf = pSubL->_bf = 0;}void _RotateLR(Node* pParent){Node* pSubL = pParent->_pleft;Node* pSubLR = pSubL->_pright;int bf = pSubL->_pright->_bf;_RotateL(pParent->_pleft);_RotateR(pParent);//if (pParent->_pright)//{if (bf == -1){pParent->_bf = 1;pSubL->_bf = 0;}else if (bf == 1){pParent->_bf = 0;pSubL->_bf = -1;}else{pParent->_bf = 0;pSubL->_bf = 0;}//}}void _RotateRL(Node* pParent){Node* pSubR = pParent->_pright;Node* pSubRL = pSubR->_pleft;int bf = pSubR->_pleft->_bf;_RotateR(pParent->_pright);_RotateL(pParent);//if (pParent->_pleft)//{if (bf == 1){pParent->_bf = -1;pSubR->_bf = 0;}else if (bf==-1){pParent->_bf = 0;pSubR->_bf = 1;}else{pParent->_bf = 0;pSubR->_bf = 0;}//}}void _InOrder(Node* pRoot){if (pRoot){_InOrder(pRoot->_pleft);cout << pRoot->_key << " ";_InOrder(pRoot->_pright);}}size_t _Height(Node* pRoot){if (NULL == pRoot)return 0;if (NULL == pRoot->_pleft&&NULL == pRoot->_pright)return 1;size_t LeftHeight = _Height(pRoot->_pleft);size_t RightHeight = _Height(pRoot->_pright);return LeftHeight > RightHeight ? LeftHeight + 1 : RightHeight + 1;}bool _IsBalanceTree(Node* pRoot){if (NULL == pRoot)return true;int LeftHeight = _Height(pRoot->_pleft);int RightHeight = _Height(pRoot->_pright);if (pRoot->_bf != RightHeight - LeftHeight || abs(pRoot->_bf) > 1)return false;return _IsBalanceTree(pRoot->_pleft) && _IsBalanceTree(pRoot->_pright);}bool _Remove(const K& key, Node* pRoot){if (pRoot == NULL)return true;Node* pParent = NULL;Node* pCur = pRoot;while (pCur){if (key < pCur->_key){pParent = pCur;pCur = pCur->_pleft;}else if (key>pCur->_key){pParent = pCur;pCur = pCur->_pright;}else{return false;}}Node* firstnode = NULL;if (pCur->_pleft && pCur->_pright){firstnode = _firstInOrder(pCur);pCur = firstnode;firstnode->_pParent = pParent;delete pCur;pCur = NULL;}    if(pCur->_pleft != NULL&&pCur->_pright == NULL){pCur->_pleft = firstnode;firstnode->_pParent = pParent;delete pCur;pCur = NULL;}if (pCur->_pleft == NULL&&pCur->_pright != NULL){pCur->_pright = firstnode;firstnode->_pParent = pParent;delete pCur;pCur = NULL;}if (pCur->_pleft == NULL&&pCur->_pright == NULL){delete pCur;pCur = NULL;}//判断pCur是pParent的左孩子还是右孩子while (pParent){if (firstnode == pParent->_pleft)pParent->_bf++;elsepParent->_bf--;if (pParent->_bf == 1 || pParent->_bf == -1)return true;else if (pParent->_bf == 0){firstnode = pParent;pParent = pParent->_pParent;}else{if (pParent->_bf == 2){if (firstnode->_bf == 1)_RotateL(pParent);else_RotateRL(pParent);}else{if (firstnode->_bf == -1)_RotateR(pParent);else_RotateLR(pParent);}break;}}return true;}Node* _firstInOrder(Node*& node){while (node->_pleft){node = node->_pleft;}return node;}private:Node* _pRoot;};




原创粉丝点击