平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

右旋:在插入二叉树的时候,根节点的右侧高度大于左侧高度,且绝对值超过了2,并且在root.左侧的值大于插入的值时发生右旋 。

  左右旋:在插入二叉树的时候,根节点的右侧高度大于左侧高度,且绝对值超过了2,并且在root.左侧的值小于插入的值时发生,先对root的左子树发生左旋,再对root右旋。

左旋:在插入二叉树的时候,根节点的左侧高度大于右侧,绝对值超过2,且root右侧的值小于插入的值,这个时候发生左旋。

  右左旋:在插入二叉树的时候,根节点的左侧高度大于右侧,绝对值超过2,且root右侧的值大于插入的值,这个时候发生右左旋。先对root的右子树发生右旋,再对root树发生左旋。

   

package com.lee.test;

/**
* 平衡二叉树 插入、删除、遍历
*/
public class AVLTree {
private class Node{
private Node left;
private Node right;
private int value;
private int height = -1;
private Node (int value){
this.value = value;
}
private Node(){ }
}
private Node head; //头
public AVLTree(){
} /**
* 获取高度
* @param root
* @return
*/
private int Height(Node root){
if (root == null){
return -1;
}else {
return root.height;
}
} /**
* 右旋
* @return
*/
private Node rotateRight(Node root){
Node temp = root.left;
root.left = temp.right;
temp.right = root;
root.height = Math.max(Height(root.left),Height(root.right)) +1; //高度设置为两者中最高的一个
temp.height = Math.max(Height(temp.left),Height(temp.right)) +1; //高度设置为两者中最高的一个
return temp;
}
/**
* 左旋
* @return
*/
private Node rotateLeft(Node root){
Node temp = root.right;
root.right = temp.left;
temp.left = root;
root.height = Math.max(Height(root.left),Height(root.right)) +1; //高度设置为两者中最高的一个
temp.height = Math.max(Height(temp.left),Height(temp.right)) +1; //高度设置为两者中最高的一个
return temp;
} /**
* 左右旋转
* @param node
* @return
*/
private Node rotateLeftRight(Node node){
node.left = rotateLeft(node.left);
return rotateRight(node);
} /**
* 右左旋转
* @param node
* @return
*/
private Node rotateRightLeft(Node node){
node.right = rotateRight(node.right);
return rotateLeft(node);
}
//插入
public Node insert(Node root ,int value){
if (root == null){
root = new Node(value);
}else if(value <root.value){ //插入左边
root.left = insert(root.left,value);
if (Height(root.left) - Height(root.right) == 2){ //需要左旋
if (value < root.left.value){
root = rotateRight(root);
}else{
root = rotateLeftRight(root);
}
}
}else{
root.right = insert(root.right,value);
if (Height(root.right) - Height(root.left) ==2) //需要右旋
{
if (value > root.right.value){
root = rotateLeft(root);
}else {
root = rotateRightLeft(root);
}
}
}
root.height = Math.max(Height(root.left),Height(root.right))+1;
return root;
} private Node deleteNode(Node root,int value) {
if(root == null) return root;//根节点null 无操作
if(value < root.value) {
root.left = deleteNode(root.left, value); //删除可能发生在左边,继续向下遍历左子树
}else if(value > root.value) {
root.right = deleteNode(root.right, value); //删除可能发生在右边,继续向下遍历右子树
}else { //找到需要删除的节点
if(root.left!=null && root.right!=null) {
//如果当前结点左右子树不为空,将问题转化为 删除一个子节点为空的节点
Node pre = root.right;
while(pre.left != null) {
pre = pre.left;
}
root.value = pre.value;
root.right = deleteNode(root.right, pre.value);
}else { //左右结点仅有一个或者都为空,删除该节点,如果有子节点 用子节点直接覆盖
root = (root.left != null) ? root.left : root.right;
}
}
//删除完成,调整平衡性
if(root == null) return root;
root.height = Math.max(Height(root.left), Height(root.right))+1;
//失衡
if(Height(root.left)-Height(root.right)>=2) {
//删除发生在右子树,模拟插入发生在左子树
if(Height(root.left.left) > Height(root.left.right)) {
//插入发生在左子树,LL旋转
return rotateLeft(root);
}else {
//LR旋转
return rotateLeftRight(root);
}
}else if(Height(root.left)-Height(root.right)<=-2){
//删除发生在左子树,模拟插入发生在右子树
if(Height(root.right.left) > Height(root.right.right)) {
//RL旋转
return rotateRight(root);
}else {
//RR旋转
return rotateRightLeft(root);
}
}
//未失衡,不做操作
return root;
} //遍历
private void print(Node node){
if (node == null){
return;
} print(node.left);
System.out.print(node.value+" ");
print(node.right);
// System.out.println();
} public void add(int value){
head = insert(head,value);
}
public void delete(int value){
head = deleteNode(head,value);
} public void show(){
print(head);
System.out.println();
}
public static void main(String args[]){
AVLTree tree = new AVLTree();
tree.add(24);
tree.add(20);
tree.add(26);
tree.add(18);
tree.add(22);
tree.add(23);
tree.add(19);
tree.add(21);
tree.add(17);
tree.add(10);
tree.add(12);
tree.add(14 );
tree.show();
tree.delete(22);
tree.show();
}
}

  

java平衡二叉树AVL数的更多相关文章

  1. Java 树结构实际应用 四(平衡二叉树/AVL树)

    平衡二叉树(AVL 树) 1 看一个案例(说明二叉排序树可能的问题) 给你一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在.  左边 BST 存在的问题分析: ...

  2. 数据结构与算法--从平衡二叉树(AVL)到红黑树

    数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树.算法的性能取决于树的形状,而树的形状取决于插入键的顺序.在最好的情况下,n个结点的树是完全平衡的,如下图"最好情况&q ...

  3. 二叉查找树、平衡二叉树(AVL)、B+树、联合索引

    1. [定义] 二叉排序树(二拆查找树)中,左子树都比节点小,右子树都比节点大,递归定义. [性能] 二叉排序树的性能取决于二叉树的层数 最好的情况是 O(logn),存在于完全二叉排序树情况下,其访 ...

  4. Java中的数是用补码表示的检验

    一.基本介绍(关于下列五个定义来自http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html#!comments,谢原 ...

  5. 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)

    二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...

  6. 【Java】PS-查看Java进程-线程数

    PS-查看Java进程-线程数 ps 线程 个数_百度搜索 查看进程的线程数命令 - CSDN博客 java命令行运行jar里的main类 - coderland - 博客园

  7. 平衡二叉树AVL - 插入节点后旋转方法分析

    平衡二叉树 AVL( 发明者为Adel'son-Vel'skii 和 Landis)是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1. 首先我们知道,当插入一个节点,从此插入点到树根 ...

  8. JAVA把毫秒数转换成日期

    JAVA把毫秒数转换成日期 systemMillonSenconds = System.currentTimeMillis();   2012-08-17 14:42 1456人阅读 评论(1) 收藏 ...

  9. java代码行数统计工具类

    package com.syl.demo.test; import java.io.*; /** * java代码行数统计工具类 * Created by 孙义朗 on 2017/11/17 0017 ...

随机推荐

  1. 小匠_碣 第三周期打卡 Task06~Task08

    Task06:批量归一化和残差网络:凸优化:梯度下降 批量归一化和残差网络 对输入的标准化(浅层模型) 处理后的任意一个特征在数据集中所有样本上的均值为0.标准差为1. 标准化处理输入数据使各个特征的 ...

  2. Go_go build 和 go install

    1.作用 go build:用于测试编译包,在项目目录下生成可执行文件(有main包). go install:主要用来生成库和工具.一是编译包文件(无main包),将编译后的包文件放到 pkg 目录 ...

  3. CentOS 7 yum配置阿里云镜像(转)

    1.下载源配置 凡是下载国外的软件,比如用npm,pip,yum有时下载速度感人,最好配置国内镜像地址 yum配置阿里云镜像参考:https://blog.csdn.net/hnmpf/article ...

  4. 0121 spring-boot-redis的使用

    redis是什么呢?redis,属于NoSQL的一种,在互联网时代,起到加速系统的作用. redis是一种内存数据库,支持7种数据类型的存储,性能1S 10w次读写: redis提供的简单的事务保证了 ...

  5. DE1-LINUX运行

    在官网下载.img文件:网址:http://download.terasic.com/downloads/cd-rom/de1-soc/linux_BSP/ 写入DE1_SOC_SD.img文件: 打 ...

  6. C++-POJ1021-2D-Nim[hash]

    哈希,对于每个点哈希一次 哈希的方式:该点到联通分量边界(上下左右)的距离和 然后分别对两个图的n个点按hash值排序,判断是否相等即可 #include <set> #include & ...

  7. bootstrap联动校验(转载)

    接触bootstrapvalidator时间不久,最近需要多个字段共同验证,网上查了一下未找到,查阅api文档,发现确实可以实现. 先看dom <div class="form-gro ...

  8. C++如何输入单行和多行带空格的字符串并将字符串倒序输出

    首先,我们知道在C++中,空格或者回车被认为是字符串的分割标志,使用cin输入string类的字符串时遇到会自动停止接收输入 例如,当如下程序时: #include <bits/stdc++.h ...

  9. 红帽 Red Hat Linux相关产品iso镜像下载【百度云】【更新7.6】

    不为什么,就为了方便搜索,特把红帽EL 5.EL6.EL7 的各版本整理一下,共享出来.原文链接正式发布 7.6 :RedHat Enterprise Server 7.6 for x86_64:rh ...

  10. python 中模块的版本号

    查看所使用的模块的版本号,以numpy为例 import numpy numpy.__version__ 查看help(numpy)时,信息太多,不想看了,如何退出,按q,即可.