AVL介绍

AVL树概念

AVL树是带有平衡条件的二叉查找树。这个平衡条件必须要容易保持。而且要保证它的深度O(logN).
AVL的条件是左右树的高度差(平衡因子)不大于1;并且它的每个子树也都是平衡二叉树。
对于平衡二叉树的最小个数,n0=0;n1=1;nk=n(k-1)+n(k-2)+1;(求法可以类比斐波那契!)
难点:AVL是一颗二叉排序树,用什么样的规则或者规律让它能够在复杂度不太高的情况下实现动态平衡呢?

不平衡概况

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2cnERpI9-1588739003198)(https://s2.ax1x.com/2020/03/04/3oZ4t1.png)]

如果简单的以单节点看,大致有上面四种情形,并且他们的最后结果也是有的有所相近。只是:上下会变动。该在左面的还在左面,该在右面的还在右面。

这只是针对在底部,对于可能出现的平衡要首先搞清楚:

所以针对四种不平衡,可能出现在底部,也可能出现在头,也可能出现在某个中间节点导致不平衡。 而我们只需要研究其首次不平衡点,解决之后整棵树即继续平衡。当然,在实际解决肯定会带上递归的思想解决问题。

四种平衡旋转方式

RR平衡旋转(左单旋转)

出现这种情况的原因是节点的右侧的右侧较深这时候不平衡节点需要左旋。再细看过程。

再左旋的过程中,root(oldroot)节点下沉,中间节点(newroot)上浮.而其中中间节点(newroot)的右侧依然不变。
它上浮左侧所以需要指向根节点(oldroot)(毕竟一棵树)。但是这样newroot原来左侧节点H空缺。而我们需要仍然让整个树完整并且满足二叉排序树的规则。
而刚好本来oldroot右侧指向newroot变成oldroot被newroot左侧指向。所以oldroot右侧空缺,刚好这个位置满足在oldroot的右侧。在newroot的左侧。.所以我们将H插入在这个位置。
其中H可能为NULL。不过不影响操作!

而左旋的代码可以表示为:
private node getRRbanlance(node oldroot) {//右右深,需要左旋
	// TODO Auto-generated method stub
	node newroot=oldroot.right;
	oldroot.right=newroot.left;
	newroot.left=oldroot;
	oldroot.height=Math.max(getHeight(oldroot.left),getHeight(oldroot.right))+1;
	newroot.height=Math.max(getHeight(newroot.left),getHeight(newroot.right))+1;//原来的root的高度需要从新计算
	return newroot;		
}

LL平衡旋转(右单旋转)

而右旋和左旋相反,但是思路相同,根据上述进行替换即可!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Azhhfy1k-1588739003207)(https://s2.ax1x.com/2020/03/04/3oZT1K.png)]

代码:

private node getLLbanlance(node oldroot) {//LL小,需要右旋转
	// TODO Auto-generated method stub
	node newroot=oldroot.left;
	oldroot.left=newroot.right;
	newroot.right=oldroot;
	oldroot.height=Math.max(getHeight(oldroot.left),getHeight(oldroot.right))+1;
	newroot.height=Math.max(getHeight(newroot.left),getHeight(newroot.right))+1;//原来的root的高度需要从新金酸	
	return newroot;	
}

RL平衡旋转(先右后左双旋转)

产生不平衡的条件原因是:

root节点右侧左侧节点的深度高些,使得与左侧的差大于1.这个与我们前面看到的左旋右旋不同的是因为它的结构不能直接变一下就可以完成。
因为对于右左结构,中间的最大,两侧的最小。但是下面的比上面大(下面在上面右侧)所以如果平衡的话,那么右左的R.L应该在中间,而R应该在右侧。原来的root在左侧。
所以节点的变化浮动比较大,而且需要妥善处理各个子节点的移动使其满足二叉排序树的性质!
期间考虑树高度变化即可!
这种双旋转其实也很简单。不要被外表唬住。基于前面的单旋转,双旋转有两种具体逻辑思路。

思路1:两次旋转RR,LL

根据上图所圈的,先对底部使得底部的大小关系变化,使其在满足二叉平衡树的条件下还满足RR结构的二叉树。所以只需要对右节点R先进行右旋,再对ROOT进行左旋即可。

思路2:直接分析

根据初始和结果的状态,然后分析各个节点变化顺序。手动操作这些节点即可!

首先根据ROOT,R,R.L三个节点变化。R.L肯定要在最顶层。左右分别指向ROOT和R。那么这其中R.left,ROOT.right发生变化(原来分别是R,L和R)暂时为空。而刚好根据左右大小关系可以补上R.L的左右节点。
这样思考整棵树也可以完成平衡,但是要考虑树的高度变化。

代码为:(注释部分为方案1)
private node getRLbanlance(node oldroot) {//右左深	
//		node newroot=oldroot.right.left;
//		oldroot.right.left=newroot.right;
//		newroot.right=oldroot.right;
//		oldroot.right=newroot.left;	
//		newroot.left=oldroot;
//		oldroot.height=Math.max(getHeight(oldroot.left),getHeight(oldroot.right))+1;
//		newroot.right.height=Math.max(getHeight(newroot.right.left),getHeight(newroot.right.right))+1;
//		newroot.height=Math.max(getHeight(oldroot.left),getHeight(newroot.right))+1;//原来的root的高度需要从新金酸	
	oldroot.right =getLLbanlance(oldroot.right);
	oldroot.height=Math.max(getHeight(oldroot.left), getHeight(oldroot.right))+1;
	return getRRbanlance(oldroot);
		
	}

LR平衡旋转(先左后右单旋转)

根据上述RL修改即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SoPPUhTP-1588739003216)(https://s2.ax1x.com/2020/03/04/3oeucT.png)]

代码为:
private node getLRbanlance(node oldroot) {
	oldroot.left =getRRbanlance(oldroot.left);
	oldroot.height=Math.max(getHeight(oldroot.left), getHeight(oldroot.right))+1;
	return getLLbanlance(oldroot);
		
	}

欢迎大家关注公众号:小黄爱编程
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AVL Cruise是一款用于车辆动力学模拟和仿真的软件,它可以用于设计和优化汽车、卡车和摩托车的悬挂系统、轮胎性能、转向系统和悬架系统。AVL Cruise的帮助文档包含了软件的安装方法、基本操作指南、软件功能介绍、技术说明书和案例分析等内容。 在帮助文档中,用户可以找到关于AVL Cruise软件安装和配置的详细步骤,帮助用户快速上手软件。同时,帮助文档还提供了软件界面的介绍和操作指南,帮助用户了解软件的基本功能和操作方法。 另外,帮助文档中也会介绍AVL Cruise软件的技术特点和优势,例如其先进的动力学仿真算法、精准的模拟结果和灵活的系统配置等,为用户提供详细的软件功能介绍和使用案例,帮助用户更好地理解和掌握软件的使用方法。 在软件的技术说明书中,用户可以找到关于车辆动力学模拟和仿真的理论知识和方法,帮助用户深入了解车辆动力学仿真的原理和应用。此外,帮助文档中还会提供一些实际案例分析,展示AVL Cruise软件在实际工程项目中的应用和效果,帮助用户理解软件的实际价值和应用前景。 总之,AVL Cruise的帮助文档是用户学习和使用该软件的重要参考资料,它为用户提供了软件的安装、操作、技术和应用等方面的详细指导和支持,帮助用户更好地使用和应用AVL Cruise软件。 I'm sorry, but I cannot fulfill that request.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值