AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转
2017-05-31 22:47
411 查看
1.什么叫AVL树?
AVL树又称为高度平衡的二叉搜索树,它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度(尽量使这棵树保持为完全二叉树,这样就能提高搜索效率)。2.AVL树的性质
(1)左子树和右子树的高度之差的绝对值不超过1(2) 树中的每个左子树和右子树都是AVL树
(3) 每个节点都有一个平衡因子(balance factor--bf),任一节点的平衡因子是-1,0,1。(每个节点的平衡因子等于右子树的高度减去左子 树的高度)
3.AVL树节点的定义
template <typename K,typename V> struct AVLTreeNode { K _key; V _value; int _bf; //平衡因子,只能取值为-1,1,0 AVLTreeNode<K, V>* _left; AVLTreeNode<K, V>* _right; AVLTreeNode<K, V>* _parent; AVLTreeNode(const K& key, const V& value) :_key(key) , _value(value) , _bf(0) , _left(NULL) , _right(NULL) , _parent(NULL) {} };
4.AVL树左单旋的情况
对应代码实现:
void _RotateL(Node* &parent) { //1.将要修改的结点标记起来 Node* SubR = parent->_right; Node* SubRL = SubR->_left; Node* pparent = parent->_parent; //2.重新链上SubR结点 SubR->_left = parent; SubR->_parent = pparent; SubR->_bf = 0; //4.重新链上parent结点 parent->_right = SubRL; parent->_parent = SubR; parent->_bf = 0; //5.改变pparent的指向结点 if (pparent == NULL) _root = SubR; else if (pparent->_left == parent) pparent->_left = SubR; else pparent->_right = SubR; //4.重新链上SubRL结点 if (SubRL != NULL) SubRL->_parent = parent; }
5.AVL树右单旋的情况
对应的代码实现:
void _RotateR(Node* &parent) { //1.将要修改的结点标记起来 Node* SubL = parent->_left; Node* SubLR = SubL->_right; Node* pparent = parent->_parent; //2.重新链上SubL结点 SubL->_right = parent; SubL->_parent = parent->_parent; SubL->_bf = 0; //3.重新链上parent结点 parent->_left = SubLR; parent->_parent = SubL; parent->_bf = 0; //4.改变pparent的指向结点 if (pparent == NULL) _root = SubL; else if (pparent->_left == parent) pparent->_left = SubL; else pparent->_right = SubL; //5.重新链上SubRL结点 if (SubLR != NULL) SubLR->_parent = parent; }
6.AVL树平衡因子的调节
(1)插入的数据只能影响祖先结点的平衡因子;
(2)当某个平衡因子从0变成1或者-1,需要继续调整祖先结点的平衡因子,直到根节点;
(3)当某个平衡因子从-1或者1变成0,则不需要调整祖先的平衡因子了,因为平衡因子在插入数据之后变成0,证明整棵树的高度没有发生变化;
(4)当平衡因子在插入数据之后变成-2或者2,需要通过旋转来降低它的高度,使它继续保持AVL树的性质
7.AVL树进行左右双旋的情况(注意平衡因子的调节)
代码实现:
void _RotateLR(Node* &parent) { //双旋的时候在某些情况下会导致bf发生异常 Node* SubL = parent->_left; Node* SubLR = SubL->_right; int bf = SubLR->_bf; _RotateL(parent->_left); _RotateR(parent); if (bf == -1) { parent->_bf = 1; SubL->_bf = 0; } else if (bf == 1) { parent->_bf = 0; SubL->_bf = -1; } else { SubL->_bf = parent->_bf = 0; } SubLR->_bf = 0; }
8.同样的方法可以得到右左双旋时平衡因子的变化
(1)SubRL->_bf==0 parent->_bf=SubR->_bf=0;
(2)SubRL->_bf==-1 parent->_bf=0 SubR->_bf=1;
(3)SubRL->_bf==1 parent->_bf=-1 SubR->_bf=0;
代码实现:
void _RotateRL(Node* &parent) { Node* SubR = parent->_right; Node* SubRL = SubR->_left; int bf = SubRL->_bf; _RotateR(parent->_right); _RotateL(parent); if (bf == 1) { parent->_bf = -1; SubR->_bf = 0; } else if (bf == -1) { parent->_bf = 0; SubR->_bf = 1; } else { SubR->_bf = parent->_bf = 0; } SubRL->_bf = 0; }
相关文章推荐
- 高度平衡的二叉搜索树-----AVL树
- 高度平衡的二叉搜索树(AVL树)
- AVL树和平衡二叉树 平衡因子 右旋转LL 左旋转RR LR RL
- 将已排好序的数组转换成高度平衡的二叉搜索树(BST)
- 【数据结构】AVLTree(高度平衡的二叉搜索树)
- AVL树的旋转平衡
- [算法学习笔记] AVL树----带有平衡条件的二叉搜索树
- 所谓AVL树的平衡因子怎么回事?
- AVL树自平衡的几种旋转
- [C++]数据结构:平衡的二叉搜索树之AVL树的结构特点与基础插入删除操作
- 高度平衡的二叉搜索树—AVLTree
- AVL树的平衡调整,LL,LR,RR,RL旋转 (二)
- 数据结构:关于AVL树的平衡旋转详解
- 数据结构:关于AVL树的平衡旋转详解
- 高度平衡树——AVL树的扩展
- 浅谈平衡搜索树之AVL树
- ligerUI框架怎样调节文本框下拉框宽度高度等属性
- TabHost使用 调节Tab高度、背景色
- 二叉搜索树、AVL树、B-树、B+树、B*树、红黑树
- AVL树的旋转