图解AVL树
1:AVL树简介
二叉搜索树在一般情况下其搜索的时间复杂度为O(logn),但某些特殊情况下会退化为链表,导致树的高度变大且搜索的时间复杂度变为O(n),发挥不出树这种数据结构的优势,因此平衡二叉树便应运而生,通过保证树的高度来保证查询的时间复杂度为O(logn),想想人类实在是太聪明了!
2:构造AVL树
在构造一棵AVL树的时候如何保持平衡呢?其手段便是通过各种旋转变换来调整以此保证整棵树的高度,调整的原则是左右子树的高度不能大于1的绝对值(平衡因子)先来介绍下旋转的方法吧。
2.1:LL型
当插入元素后构成LL型,如下图所示,则以2为支,高右转,把3右旋下来保证平衡。
2.2:RR型
当插入元素后构成RR型,如下图所示,则以2为支,高左转,把1左旋转下来保证平衡。
2.3:LR型
当插入元素后构成LR型,如下图所示,先2,3整体左旋,在根据LL型进行右旋转来保证平衡。
2.4:RL型
当插入元素后构成RL型,如下图所示,先将5右转,在与6进行交换,在根据RR型进行旋转来保证平衡。
2.5:其他情况
当因为插入一个元素而导致出现两个不平衡点,应该调整距离插入节点最近的不平衡点
2.6:自测题
测试题:以关键字序列{16、3、7、11、9、26、18、14、15}构造一颗AVL树
2.7:java实现AVL的构造
package AVL;
/**
* @author admin
* @version 1.0.0
* @ClassName AVLTree.java
* @Description TODO
* @createTime 2020年03月30日 18:28:00
*/
public class AVLTree {
/**
* 获取左右节点的高度差,即平衡因子
* @param root
* @return
*/
public int getBalance(Node root) {
return root==null?0:getHeight(root.left)-getHeight(root.right);
}
/**
* 获取节点的高度
* @param root
* @return
*/
public int getHeight(Node root) {
return root == null ? 0 : root.height;
}
/**
* 更新节点的高度
* @param root
* @return
*/
private int updateHeight(Node root) {
if (root == null)
return 0;
return Math.max(updateHeight(root.left), updateHeight(root.right)) + 1;
}
/**
* LL型,右旋操作
*
* @param root
* @return
*/
public Node rightRotate(Node root) {
Node node = root.left;
root.left = node.right;
node.right = root;
root.height = updateHeight(root);
node.height = updateHeight(node);
return node;
}
/**
* RR型,左旋操作
* @param root
* @return
*/
public Node leftRotate(Node root) {
Node node = root.right;
root.right = node.left;
node.left = root;
root.height = updateHeight(root);
node.height = updateHeight(node);
return node;
}
public Node insert(Node node, int data) {
//当节点为空,直接插入
if (node == null) {
return (new Node(data));
}
//当插入元素<node.data,往node的左子树进行插入;>node.data,往node的右子树插入
if (node.data > data) {
node.left = insert(node.left, data);
} else {
node.right = insert(node.right, data);
}
//更新节点的高度
node.height = updateHeight(node);
//获取平衡因子(左子树高度-右子树高度)
int balDiff = getBalance(node);
// 右旋
if (balDiff > 1 && data < node.left.data) {
return rightRotate(node);
}
// 左旋
if (balDiff < -1 && data > node.right.data) {
return leftRotate(node);
}
// 先左旋在右旋
if (balDiff > 1 && data > node.left.data) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
// 先右旋在左旋
if (balDiff < -1 && data < node.right.data) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
return node;
}
}
class Node {
int data;
Node left;
Node right;
int height;
public Node(Integer data) {
this.data = data;
height = 1;
}
}
3:AVL树的删除
3.1:删除叶子节点
3.2:删除只拥有左子树或右子树的节点
3.3:删除既拥有左子树又有右子树的节点
3.4:自测题
将上一道自测题的图依次删除16,15,11节点,画出最后的结果
参考链接
数据可视化网站: https://visualgo.net/zh
哔哩哔哩讲AVL:https://www.bilibili.com/video/BV1xE411h7dd
图解AVL树的更多相关文章
- AVL树的插入操作(旋转)图解
=================================================================== AVL树的概念 在说AVL树的概念之前,我们需要清楚 ...
- 平衡二叉树,AVL树之图解篇
学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建 ...
- 图解数据结构树之AVL树
AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节点的两个子 ...
- 二叉搜索树的平衡--AVL树和树的旋转(图解)
二叉搜索树只有保持平衡时其查找效率才会高. 要保持二叉搜索树的平衡不是一件易事.不过还是有一些非常经典的办法可以做到,其中最好的方法就是将二叉搜索树实现为AVL树. AVL树得名于它的发明者 G.M. ...
- 图解:平衡二叉树,AVL树
学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建 ...
- 二叉树之AVL树的平衡实现(递归与非递归)
这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...
- AVL树平衡旋转详解
AVL树平衡旋转详解 概述 AVL树又叫做平衡二叉树.前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树).由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, ...
- AVL树(查找、插入、删除)——C语言
AVL树 平衡二叉查找树(Self-balancing binary search tree)又被称为AVL树(AVL树是根据它的发明者G. M. Adelson-Velskii和E. M. Land ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
随机推荐
- 使用PyTorch进行迁移学习
概述 迁移学习可以改变你建立机器学习和深度学习模型的方式 了解如何使用PyTorch进行迁移学习,以及如何将其与使用预训练的模型联系起来 我们将使用真实世界的数据集,并比较使用卷积神经网络(CNNs) ...
- 模型压缩一半,精度几乎无损,TensorFlow推出半精度浮点量化工具包,还有在线Demo...
近日,TensorFlow模型优化工具包又添一员大将,训练后的半精度浮点量化(float16 quantization)工具. 有了它,就能在几乎不损失模型精度的情况下,将模型压缩至一半大小,还能改善 ...
- 图像配准:从SIFT到深度学习
图像配准(Image Registration)是计算机视觉中的基本步骤.在本文中,我们首先介绍基于OpenCV的方法,然后介绍深度学习的方法. 什么是图像配准 图像配准就是找到一幅图像像素到另一 ...
- Input标签中属性的注意点
readonly 只读字段,即用户不可更改,但可以通过tab切换到该字段,还可以选中复制该字段 step 输入合法的数字间隔,当step属性的值为负数或0时默认为1,可以配合max,min属性来创建合 ...
- mongodb服务器启动
以配置文件启动服务器: mongod --config /usr/local/mongodata/config/mongodb.conf(配置文件路径) 客户端启动: mango 关闭mongodb的 ...
- python fabric 练习记录
https://blog.csdn.net/freeking101/article/details/81103945 fabric 域名
- 别人家的 InfluxDB 实战 + 源码剖析
1. 前几次的分享,我们多次提到了下图中 Metrics 指标监控的 Prometheus.Grafana,而且 get 到了 influxdata 旗下的 InfluxDB 的入门技能. 本次,我们 ...
- jenkins 脱机下 安装插件失败
1.首次进入,提示离线 2.网上给出了绝大部分答案是进入Manage Plugins 中在高级下将升级站点的https换成http,但是都没解决我的问题 还是报错,用了大部分时间查阅 最终才发现问题 ...
- Linux(Fedora)系统下配制8086汇编环境
1.到www,nasm.us下载nasm 2.解压并安装nasm #tar -xzvf nasm-2.11.08.tar.gz #cd nasm-2.11.08 #./configure #make ...
- javascript入门 之 用bootstrap-table写一个表格
方法1(对普通的 table 设置 data-toggle="table" 即可): <!DOCTYPE html> <html> <head> ...