C++平衡二叉树(AVL)
来源:互联网 发布:linux下查看用户权限 编辑:程序博客网 时间:2024/06/16 19:25
平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
当二叉树不平衡时,可以通过左单旋,右单旋,左右双旋,右左双旋的方式将它调整平衡;
平衡因子=左右子树高度之差[-1,1]
如图:
左单旋:
右单旋:
左右双旋:
右左双旋:
#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{public: AVLTree() :_pRoot(NULL) {} bool Insert(const K& key, const V& value) { if (_pRoot == NULL) { _pRoot = new AVLTreeNode<K,V>(key,value); return true; } AVLTreeNode<K, V>* pCur = _pRoot; AVLTreeNode<K, V>* parent = NULL; while (pCur) { //若节点存在,则不必插入 //若节点的值小于key,则key插入节点的右子树 //若节点的值大于key,则key插入节点的左子树 if (key == pCur->_key) return false; if (key > pCur->_key) { parent = pCur; pCur = pCur->pRight; } else if(key < pCur->_key) { parent = pCur; pCur = pCur->pLeft; } } //插入节点,并给出孩子节点与双亲结点的关系 pCur = new AVLTreeNode<K,V>(key, value); if (key>parent->_key) { parent->pRight = pCur; pCur->pParent = parent; } else { parent->pLeft = pCur; pCur->pParent = parent; } //更新平衡因子(右子树高度-左子树高度[-1,1]) while (parent) { //若当前节点是双亲结点的左孩子,平衡因子-1 //若当前节点是双亲结点的右孩子,平衡因子+1 if (parent->pLeft == pCur) parent->_bf--; if (parent->pRight == pCur) parent->_bf++; if (parent->_bf == 0) return true; else { if (parent->_bf == 1 || parent->_bf == -1) { pCur = parent; parent = parent->pParent; } else { //同号单旋(正左负右),异号双旋 if (parent->_bf == 2) { if (pCur->_bf == -1)//右左双旋 _RotateRL(parent); else if (pCur->_bf == 1)//左单旋 _RotateL(parent); } else if (parent->_bf == -2) { if (pCur->_bf == 1)//左右双旋 _RotateLR(parent); else if (pCur->_bf == -1)//右单旋 _RotateR(parent); } break; } } } return true; }private: //右单旋 void _RotateR(AVLTreeNode<K, V>*& parent){ AVLTreeNode<K, V>* subL = parent->pLeft; AVLTreeNode<K, V>* subLR = subL->pRight; parent->pLeft = subLR; if (subLR != NULL) subLR->pParent = parent; subL->pRight = parent; subL->pParent = parent->pParent; AVLTreeNode<K, V>* rPrarent = parent->pParent; parent->pParent = subL; if (rPrarent == NULL) { _pRoot = subL; } else { if (rPrarent->pLeft == parent) rPrarent->pLeft = subLR; else rPrarent->pRight = subLR; } parent->_bf = subL->_bf = 0;} //左单旋void _RotateL(AVLTreeNode<K, V>*& parent){ AVLTreeNode<K, V>* subR = parent->pRight; AVLTreeNode<K, V>* subRL = subR->pLeft; parent->pRight = subRL; if (subRL != NULL) subRL->pParent =parent; subR->pLeft = parent; subR->pParent = parent->pParent; AVLTreeNode<K, V>* rPrarent = parent->pParent; if (rPrarent == NULL) _pRoot = subR; else { if (rPrarent->pLeft == parent) rPrarent->pLeft = subR; else rPrarent->pRight = subR; } parent->_bf = subR->_bf = 0;}//右左双旋void _RotateRL(AVLTreeNode<K, V>*& parent){ AVLTreeNode<K, V>* subR = parent->pRight; AVLTreeNode<K, V>* subRL = subR->pLeft; int bf = subRL->_bf;//0.1,-1 //右单旋 _RotateR(parent->pRight); //左单旋 _RotateL(parent); if (bf == -1) { parent->_bf = 0; subR->_bf = 1; subRL->_bf = 0; } else if (bf == 1) { parent->_bf = -1; subR->_bf = 0; subRL->_bf = 0; }}//左右双旋void _RotateLR(AVLTreeNode<K, V>*& parent){ AVLTreeNode<K, V>* subL = parent->pLeft; AVLTreeNode<K, V>* subLR = subL->pRight; int bf = subLR->_bf;//0,1,-1 //左单旋 _RotateL(parent->pLeft); //右单旋 _RotateR(parent); if (bf == -1) { parent->_bf = 1; subLR->_bf = 0; subL->_bf = 0; } else if (bf==1) { parent->_bf = 0; subLR->_bf = 0; subL->_bf = -1; }}private: AVLTreeNode<K, V>* _pRoot;};测试函数:void AVLTreeTest(){ AVLTree<int, int> at; int arr[] = { 50, 40, 60, 30, 45, 42 }; //int arr[] = { 50, 40, 30, 45, 20, 60 }; for (int idx = 0; idx < sizeof(arr) / sizeof(arr[0]); idx++) { at.Insert(arr[idx],arr[idx]); }}
0 0
- 二叉平衡树(AVL)-C语言
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 平衡二叉树(AVL树) ----- C语言
- 标准C实现的平衡二叉树(AVL)
- AVL平衡二叉查找树实现(C语言版本)
- 【修改】C实现平衡二叉树---AVL
- C语言实现AVL-平衡二叉树
- AVL 平衡二叉树
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- AVL 平衡二叉树
- avl平衡二叉树
- 二叉平衡树AVL
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 平衡二叉树 AVL
- MCU非常重要的通信接口--UART的调试
- Linux下模拟多线程的并发并发shell脚本
- createQuery is not valid without active transaction
- RSA解密算法优化(java)
- emWIN中实现了通用的链表结构
- C++平衡二叉树(AVL)
- jsp获得绝对路径
- 设计模式之单例设计模式
- 关于Android面试中如何应对内存优化
- Emulating dynamic scoping in GNU R
- SpringMVC 中整合JSON、XML视图一
- Java简介以及开发环境配置
- MTK lk源码解析5( lk 阶段aboot.c 解析)
- jQuery实现ajax