AVl树

来源:互联网 发布:最新php漏洞 编辑:程序博客网 时间:2024/05/21 16:23

AVL树是高度平衡的二叉搜索树

特征:

1.左右子数的高度差不超过1(因为可能有4个节点)

2.树中每个左子树,右子树都是AVL树

3.每个节点都有一个平衡因子,(每个节点的平衡因子等于右子树的高度减去左子树的高度),每个节点的平衡因子为1/0/-1

效率:

AVL树的高度为N,其高度可以保持在log2^N ,插入,删除,查找等时间复杂度也都是log2^N


因为AVL是高度平衡的二叉搜索树,插入以后就可能会导致它不平衡,所以要进行旋转

1左旋:

void RotateL(Node* parent){Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;if (SubRL){SubRL->_parent = parent;}SubR->_left = parent;Node* ppNode = parent->_parent;parent->_parent = SubR;if (ppNode == NULL){_root = SubR;SubR->_parent = NULL;}else{if (ppNode->_left == parent){ppNode->_left = SubR;}else{ppNode->_right = SubR;}SubR->_parent = ppNode;}SubR->_bf = parent->_bf =0}


2.右旋

void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;Node* ppNode = parent->_parent;parent->_parent = subL;if (ppNode == NULL){_root = subL;subL->_parent = NULL:}else{if (ppNode->_right = _root){ppNode->_right = subL;}elseppNode->_left = subL;subL->_parent = ppNode;}subL->_bf = parent->_bf = 0;}


3.左右双旋

void RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = parent->_right;int bf = subLR->_bf;RotateL(parent->_left);RotateR(parent);if (bf == 1){subL->_bf = -1;parent->_bf = 0}if (bf == -1){subL->_bf = 0;parent->_bf = 1;}else{subL->_bf = parent->_bf = 0;}subLR->bf = 0;}


4.右左双旋

        void RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subR->_bf;RotateR(parent->_right);RotateL(parent);if (bf == 1){parent->_bf = -1;subRL->_bf = 0;}if (bf == -1){parent->_bf = 0;subRL->_bf = 1;}else{subR->_bf = parent->_bf = 0;}subRL->_bf = 0;}


整体实现:


#include<iostream>using namespace std;template<class K,class V>struct AVLTreeNode{K _key;V _value;AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;int _bf;AVLTreeNode(const K& k, const V& v): _key(key), _value(value), _left(NULL), _right(NULL), _parent(NULL), _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)                //二叉搜索树的特性,若key大于cur->_key则为右,小于则为左{if (cur->_key < key){parent = cur;cur = cur->_right;}if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key, value);if (parent->_key < key){parent->_right = cur;cur->_parent = parent;}else{parent->_left = cur;cur->_parent = parent;}
//插入后更新bfwhile (parent){if (cur == parent->_left){parent->_bf--;}else{parent->_bf++}if (parent->_bf == 0)//若bf=0,则平衡
                             break;if (parent->_bf == 1 || parent->_bf == -1)//等于1的话继续向上调整{cur = parent;cur=parent->_parent;}else{if (parent->_bf == 2){if (cur->_bf == 1){RotateL(parent);//左旋}else      //cur->_bf==-1{RotateRL(parent);//右左双旋}}else              //parent->_bf = -2{if (cur->_bf == -1){RotateR(parent);//右旋}else{RotateLR(parent);//左右双旋}}break;}}return true;}void RotateL(Node* parent)//左{Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;if (SubRL){SubRL->_parent = parent;}SubR->_left = parent;Node* ppNode = parent->_parent;parent->_parent = SubR;if (ppNode == NULL){_root = SubR;SubR->_parent = NULL;}else{if (ppNode->_left == parent){ppNode->_left = SubR;}else{ppNode->_right = SubR;}SubR->_parent = ppNode;}SubR->_bf = parent->_bf =0}void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;Node* ppNode = parent->_parent;parent->_parent = subL;if (ppNode == NULL){_root = subL;subL->_parent = NULL:}else{if (ppNode->_right = _root){ppNode->_right = subL;}elseppNode->_left = subL;subL->_parent = ppNode;}subL->_bf = parent->_bf = 0;}void RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = parent->_right;int bf = subLR->_bf;RotateL(parent->_left);RotateR(parent);if (bf == 1){subL->_bf = -1;parent->_bf = 0}if (bf == -1){subL->_bf = 0;parent->_bf = 1;}else{subL->_bf = parent->_bf = 0;}subLR->bf = 0;}void RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subR->_bf;RotateR(parent->_right);RotateL(parent);if (bf == 1){parent->_bf = -1;subRL->_bf = 0;}if (bf == -1){parent->_bf = 0;subRL->_bf = 1;}else{subR->_bf = parent->_bf = 0;}subRL->_bf = 0;}protected:void _Inorder(Node* root){if (root = NULL){return;}_Inorder(root->_left);cout << root->_key << ;_Inorder(root->right);}private:Node* _root;};