平衡二叉树
来源:互联网 发布:剑三成女金发脸型数据 编辑:程序博客网 时间:2024/05/14 14:24
AVL树是带有平衡条件的二叉查找树,能保证树的深度是O(logN)。平衡条件--每个节点的左子树和右子树的高度最多差1。
*证明:假设高度为h且节点数最少的AVL树中,节点数为S(h)。
树由根节点,左子树和右子树组成。树的高度为h,所以必然有一个子树的高度为h-1,为了达到最少节点的目的且满足左右子树的高度最多差1的条件,另外一棵子树高度则为(h-1)-1 =h-2。树是满足最少节点数的,所以左右子树的节点数也应该对应的是满足高度为h-1和h-2的最少节点数,S(h-1)和S(h-2)
则有 S(h) = S(h-1) + S(h-2) + 1,其中S(0) = 1,S(1) = 2。式子稍作变换,S(h)+1= ( S(h-1)+1) + ( S(h-2)+1),即是斐波那契数列形式。
那么高度为h的AVL树的节点数 N >= S(h) = Ω(φ^h) ---> h = O( logN).
*旋转
树的平衡靠旋转来维持。
把进行插入操作后必须重新平衡的节点叫做a。当树的高度不平衡时,a点的两颗子树的高度差为2,不平衡可能出现在下面四种情况中:
1.对a的左儿子的左子树进行一次插入。
2.对a的左儿子的右子树进行一次插入。
3.对a的右儿子的左子树进行一次插入。
4.对a的右儿子的右子树进行一次插入。
其中1,4两种情况是对称的,2,3是对称的。
第一种情况是插入到“外边”的情况(1,4),通过单旋转进行调整。
第二种情况是插入到“内边”的情况(2,3),通过双旋转进行调整。
template<typename T>class AvlTree{ struct Node; typedef Node * Position; public: AvlTree() { root_ = NULL;} void insert( const T &x) { insert( x, root_);} void remove( const T &x) { remove( x, root_);} Position find( const T &x) { return find( x, root_);} Position findMin( ) { return findMin( root_);} Position findMax( ) { return findMax( root_);} int height() { return height(root_);} virtual ~AvlTree() { makeEmpty( root_);} private: struct Node { T data; Node * left; Node * right; int height; }; Position root_; void makeEmpty( Position & t) { if( t==NULL) return; makeEmpty( t->left); makeEmpty( t->right); delete t; } int height( const Position & t) const { if ( t==NULL) return -1; else return t->height; } Position find( const T &x, const Position & t) const { if ( t==NULL) return NULL; if( x<t->data) return find( x, t->left); else if( x>t->data) return find( x, t->right); else return t; } Position findMin( const Position &t) const { if( t==NULL) return NULL; if( t->left!=NULL) return findMin( t->left); else return t; } Position findMax( const Position &t) const { if( t==NULL) return NULL; if( t->right!=NULL) return findMax( t->right); else return t; } void singleRotateWithLeft( Position & t) { Position tmp = t; t = t->left; tmp->left = t->right; t->right = tmp; tmp->height = max( height( tmp->left), height( tmp->right)) +1; t->height = max( height( t->left), height( t->right)) +1; } void singleRotateWithRight( Position & t) { Position tmp = t; t = t->right; tmp->right = t->left; t->left = tmp; tmp->height = max( height( tmp->left), height( tmp->right))+1; t->height = max( height( t->left), height( t->right))+1; } void doubleRotateWithLeft( Position & t) { singleRotateWithRight( t->left); singleRotateWithLeft( t); } void doubleRotateWithRight( Position & t) { singleRotateWithLeft( t->right); singleRotateWithRight( t); } void rotate( Position & t) { if( !t) return; int dist = height( t->left) - height( t->right); // 左右子树高度差 if( dist<=1 && dist>=-1) return; if( dist == 2) // 左子树高 { if( height( t->left->left) > height( t->left->right)) //外边节点高出,单旋 singleRotateWithLeft(t); else //内边节点高出,双旋 doubleRotateWithLeft(t); } else if ( dist == -2) //右子树高 { if( height( t->right->right)> height( t->right->left)) //外边节点高出,单旋 singleRotateWithRight(t); else //内边节点高出,双旋 doubleRotateWithRight(t); } } void insert( const T & x, Position & t) { if( t==NULL) { t = new Node; t->data = x; t->left = t->right = NULL; t->height = 0; return; } if( x < t->data) insert( x, t->left); else if( x > t->data) insert( x, t->right); t->height = max( height(t->left), height( t->right)) + 1; //更新高度 rotate(t); } void remove( const T & x, Position & t) { if( t==NULL) return; if( x < t->data) remove( x, t->left); else if ( x > t->data) remove( x, t->right); else if( t->left && t->right) { Position tmp; switch( x%2) //左右子树同时存在,查找左子树最大节点或者右子树最小节点替换 { case 0: tmp = findMin( t->right); t->data = tmp->data; remove( t->data, t->right); break; case 1: tmp = findMax( t->left); t->data = tmp->data; remove( t->data, t->left); break; } } else { Position tmp = t; t = t->left ? t->left : t->right; delete tmp; } if( t) t->height = max( height( t->left), height( t->right))+1; //更新高度 else return; rotate( t); }};
参考《数据结构与算法分析-c++语言描述》-Mark Allen Weiss
- 平衡二叉树平衡法则
- 二叉树--二叉平衡树
- 平衡二叉树的
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉查找树
- 平衡二叉树 详解
- 平衡二叉树
- 平衡二叉树
- AVL 平衡二叉树
- 平衡二叉树
- 平衡二叉树-红黑树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- C++的基本数据类型
- KVC
- Eclipse配色方案插件
- ios 7 以上只要这几句话,html马上转变回正常排版
- 使用尾注添加参考文献并删除尾注中的横线和空格
- 平衡二叉树
- 正则表达式使用详解
- Drp是什么 Distribution Resource Planning的缩写
- linux下安装nginx
- 用Eclipse 统计代码行数小技巧
- JQuery和Servlet实现文件上传进度条,能显示上传速度,上传的百分比等
- TIJ学习笔记-匿名类
- java设计模式(2):工厂方法模式(Factory Method)
- IO-03. 求整数均值(10)