AVL树的插入操作(旋转)图解
AVL树的概念


AVL树的插入
template<class K>
struct AVLTreeNode
{
K _key;
int _bf;
AVLTreeNode<K, V>* _left;
AVLTreeNode<K, V>* _right;
AVLTreeNode<K, V>* _parent; AVLTreeNode(const K& key, const V& value)
:_key(key),
_bf(),
_left(NULL),
_right(NULL),
_parent(NULL)
{}
};












程序代码:
bool Insert(const K& key, const V& value)
{
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}
Node* pcur = _root;
Node* parent = NULL;
while (pcur)
{
if (pcur->_key == key)
return false;
else if (pcur->_key < key)
{
parent = pcur;
pcur = pcur->_right;
}
else
{
parent = pcur;
pcur = pcur->_left;
}
}
if (parent->_key < key)
{
pcur = parent->_right = new Node(key, value);
pcur->_parent = parent;
}
else
{
pcur = parent->_left = new Node(key, value);
pcur->_parent = parent;
} while (parent)
{
//修正平衡因子
if (pcur == parent->_left)
{
parent->_bf--;
}
if (pcur == parent->_right)
{
parent->_bf++;
}
//
if (parent->_bf == )
break;
else if (parent->_bf == - || parent->_bf == )
{
pcur = parent;
parent = pcur->_parent;
}
else //parent->bf -2 || 2
{ if (parent->_bf == -)
{
if (pcur->_bf == -) //右单旋
RotateR(parent);
else //左右双旋
RotateLR(parent);
}
else
{
if (pcur->_bf == ) //左单旋
RotateL(parent);
else //右左双旋
RotateRL(parent);
}
break;
}
}
return true;
}
>>旋转
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
//换指向
parent->_left = subLR;
subL->_right = parent; if (subLR)
{
subLR->_parent = parent;
} Node* PParent = parent->_parent; //判断parent是否有父节点
if (PParent)
{
if (parent == PParent->_left)
{
PParent->_left = subL;
subL->_parent = PParent;
}
else
{
PParent->_right = subL;
subL->_parent = PParent;
}
}
else
{
_root = subL;
subL->_parent = NULL;
}
parent->_parent = subL;
//修改bf
subL->_bf = ;
parent->_bf = ;
} //
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
//调整指向
subR->_left=parent;
parent->_right = subRL; if (subRL) //如果subRL非空
{
subRL->_parent = parent;
} Node* PPNode = parent->_parent;
if (PPNode)
{
if (PPNode->_left == parent)
PPNode->_left = subR;
else
PPNode->_right = subR; //subR的父节点改变
subR->_parent = PPNode;
}
else
{
_root = subR; //根节点
subR->_parent = NULL;
}
parent->_parent = subR;
/*修改bf*/
parent->_bf = subR->_bf = ;
} //双旋(左右、、右左)
void RotateRL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
int bf = subRL->_bf; RotateR(parent->_right);
RotateL(parent); //调整subR和parent的平衡因子
if (bf == -)
subR->_bf = ; // subR的bf在左旋中已经置0了,这里就没有再写
else if (bf == )
parent->_bf = -; else
{
parent->_bf = ;
subRL->_bf = ;
}
} void RotateLR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
RotateL(parent->_left);
RotateR(parent); //调整parent和subL的平衡因子
if (bf == -)
parent->_bf = ; //subL的bf在左旋中已经置0了,这里就没有再写
else if (bf == )
subL->_bf = -; //parent的bf在左旋中已经置0了
else
{
subL->_bf = ;
parent = ;
}
}
AVL树的插入操作(旋转)图解的更多相关文章
- AVL树的插入和删除
一.AVL 树 在计算机科学中,AVL树是最早被发明的自平衡二叉查找树.在AVL树中,任一节点对应的两棵子树的最大高度差为 1,因此它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下的时间复杂度 ...
- AVL 树的插入、删除、旋转归纳
参考链接: http://blog.csdn.net/gabriel1026/article/details/6311339 1126号注:先前有一个概念搞混了: 节点的深度 Depth 是指从根 ...
- AVL树的单双旋转操作
把必须重新平衡的节点称为å.对于二叉树,å的两棵子树的高度最多相差2,这种不平衡可能有四种情况: 对å的左儿子的左子树进行插入节点(左-左) 对å的左儿子的右子树进行插入节点(左-右) 对å的右儿子的 ...
- AVL树的插入删除查找算法实现和分析-1
至于什么是AVL树和AVL树的一些概念问题在这里就不多说了,下面是我写的代码,里面的注释非常详细地说明了实现的思想和方法. 因为在操作时真正需要的是子树高度的差,所以这里采用-1,0,1来表示左子树和 ...
- AVL树的插入与删除
AVL 树要在插入和删除结点后保持平衡,旋转操作必不可少.关键是理解什么时候应该左旋.右旋和双旋.在Youtube上看到一位老师的视频对这个概念讲解得非常清楚,再结合算法书和网络的博文,记录如下. 1 ...
- 第七章 二叉搜索树 (d2)AVL树:插入
- 创建AVL树,插入,删除,输出Kth Min
https://github.com/TouwaErioH/subjects/tree/master/C%2B%2B/PA2 没有考虑重复键,可以在结构体内加一个int times. 没有考虑删除不存 ...
- 数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作
AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1). 也就是说,AVL树,本质上 ...
- AVL树(查找、插入、删除)——C语言
AVL树 平衡二叉查找树(Self-balancing binary search tree)又被称为AVL树(AVL树是根据它的发明者G. M. Adelson-Velskii和E. M. Land ...
随机推荐
- JavaIO流(02)RandomAccessFile类详解
RandomAccessFile类 该类主要是对文件内容进行操作,可以随机的读取一个文件中指定位置的数据: 但是如果想实现这样的功能,则每个数据的长度应该保持一致: 构造方法: 接受File类 ...
- [置顶] 新修改ADB,支持Android 4.2 系统 ,全部中文命令,手机屏幕截图等等
发过好几个ADB的工具,有很多朋友用了之后给我反馈了不少的意见和bug,这里非常感谢他们,所以今天花了一天的时间重新整理了一下ADB,并且修改了这些BUG.也有朋友建议我给一个修改列表,今天发这个帖子 ...
- ASP.NET MVC- Area 使用
ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Cont ...
- 在自定义的dwt文件中调用page_header.lbi和page_footer.lbi
昨天下午接到需求说要增加一个新的页面,作为优惠活动规则的介绍之用,之前对ecshop各种修改,但是这次自己做页面还是第一次,文件太多,函数也太多,一个一个的读过来时间很头疼的事情,于是就参照goods ...
- pygame “音乐盒”---- 播放一首歌& 点击对话框后背景以及对话框大小改变
有时,你用pygame写的游戏也许需要播放一些背景音乐,该怎么做呢,直接上代码: 下面的代码,有关于: 1>设置对话框图标.大小.标题 2>播放音乐 3>设置背景图片,以及获取背景图 ...
- WinFrom界面框架之WeifenLuo.WinFormsUI.Docking + OutLookBar
本文转载:http://www.cnblogs.com/luomingui/p/3329763.html WeifenLuo.WinFormsUI.Docking + OutLookBar结合使用的效 ...
- MEF 编程指南(一):在应用中托管 MEF
在应用程序中托管(Hosing) MEF 涉及到创建组合容器(CompositionContainer) 实例,添加可组合部件(Composable Parts),包括应用程序宿主(Host)本身并进 ...
- contiki makefile框架分析 < contiki学习之一 >
在linux下的工程编译,基本都可以使用makefile这个工具来完成.Contiki OS亦如此,下面分析contiki整个Makefile的框架,对makefile的具体内容暂不做分析.本文依赖于 ...
- SAP BW 例程(Routine)【开始例程、关键值或特性的例程、结束例程】
定义 可以使用例程定义关键值或特性的复杂的转换规则. 例程是本地 ABAP 类,它们包括预定义的定义和实施范围.进站和出站参数的 TYPES及方法签名都存储在定义范围中.实际例程创建于实施范围中.使用 ...
- Codeforces Beta Round #85 (Div. 1 Only) B. Petya and Divisors 暴力
B. Petya and Divisors Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/111 ...