您现在的位置是:首页 > 文章详情

图解平衡二叉搜索树

日期:2021-06-12点击:332

本博文使用图文描述了平衡二叉搜索树的插入过程:

1: 寻找插入点

2:向上回溯寻找失去平衡的节点 (状态不等于EH的节点)

3:旋转

平衡二叉搜索树

        平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。 数值关系,右孩子的值 > 当前节点的值 > 左孩子的值。

平衡二叉搜索树节点的状态

1:左子树比右子树高  LH

2:左子树和右子树一样高 EH

3:右子树比左子树高 RH

 

 

如上图每个节点的状态如下。

 

TreeNode 的定义

 static final class TreeNode<T> { TreeStatus treeStatus = TreeStatus.EH; T value; TreeNode<T> left; TreeNode<T> right; TreeNode<T> parent; public TreeNode(T value) { this.value = value; } public TreeNode(T value, TreeNode<T> p) { this.value = value; this.parent = p; } public String toString() { return "value=" + value.toString(); } }

 

 

搜索插入点   

以向平衡二叉树插入105为例。

搜索过程

105 gt 90 搜索90的右子树

105 gt 100 搜索100的右子树

105 lt 130 搜索130的左子树

105 lt 107 搜索107的左子树

107的左子树为空,停止搜索, 105为107的左孩子。

插入新点节之后搜索途中的节点的状态发生改变,需要回溯更改每个节点的状态。

107节点的状态为EH,105为107的左孩子,所以107的状态更改为LH,

130节点的状态为EH,107为130的左孩子,所以130的状态更改为LH,

100节点的状态为RH,  130 为100的右孩子, 所以 100节点失去平衡。

向上回溯的图解如下。

情况1:  回溯途中所有节点的状态都为EH, 那么树的平衡性不会发生改变。

直观一点的图。

向上回溯的路径为:

在插入54节点之前,所有节点的状态为EH,但是在插入54节点之后。

51 由EH---> RH

55 由EH--->LH

50 由EH---> RH

100 由EH--->LH

 

如果me是p的左孩子,那么p的状态改为LH,

如果me是p的右孩子,那么p的状态改为RH。

p=p.parent ;

me=me.parent;

情况2:回溯的途中遇到了第一个状态不为EH的节点,假设该节点为pp。

 

 

由pp,p来决定pp树是否失去平衡。

假设pp的状态为LH,

如果p为pp的左孩子,那么pp树将会失去平衡。  如果p的状态为LH,那么进行LL旋转,如果p的状态为RH,那么进行LR旋转。

如果p为pp的右孩子,那么pp树将维持平衡,并且pp的状态需要修改为EH.

平衡二叉树有6个插入点:

当插入点为1或者2时, 引起LL旋转。

当插入点为3或者4时,引起LR旋转。

当插入点为5或者6时,不会引发旋转。

由(pp.treeStatus, p.treeStatus)来决定做那种旋转。。。

 

镜像的pp的状态为RH;

下面开始讲旋转:

LL 旋转

pp为失衡的节点。 p为pp的左孩子,me为p的左孩子, xpp为pp的父节点。

 

步骤1: pr = p.right;

步骤2: p.pright = pp;  pp.parent = p;

步骤3: pp.left = pr ;   pr.parent = pp ;

步骤4: p.parent=xpp , 确定p是xpp的左孩子还是右孩子

重点说明 如果xpp为空,则p节点为新的root节点。

旋转之后 p和pp节点的状态均为EH。

LR旋转

pp为失衡的节点。 p为pp的左孩子,me为p的右孩子, xpp为pp的父节点。

步骤1 : mel =me.left;  mer= me.right 

步骤2:  me.left = p ;  me.right = pp;  p.parent = me,  pp.parent = me ;   

步骤3:  p.right = mel ; pp.left = mer ;  mel.parent = p ;  mer.parent = pp ;

步骤4: me.parent = xpp ;    确定me是xpp的左孩子还是右孩子

重点说明 如果xpp为空,则me节点为新的root节点。

状态的改变: 

如果me的状态为LH 那么p的状态为EH , pp的状态为RH;

如果me的状态为RH 那么p的状态为LH,  pp的状态为EH ;

如果me的状态为EH 那么p的状态为EH , pp的状态为EH;

旋转完成之后me的状态一定为EH。

 

RR旋转和LL旋转是镜像关系。

RL和LR是镜像关系。

 

本博文讲述了平衡二叉搜索树的插入过程:

1: 寻找插入点

2:向上回溯寻找失去平衡的点pp (pp,p,me)。 (即向上回溯寻找到状态不等于EH的点)

3:旋转

如果对您理解平衡二叉搜索树有帮助还请帮忙点赞。

如果您发现博文的描述有错误或者漏洞,请发表评论。

转载请注明博文出处。

 

实现见   https://gitee.com/tuerqidi/avl

 

原文链接:https://my.oschina.net/qidis/blog/5077095
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章