平衡二叉树(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. 小匠第二周期打卡笔记-Task05

    一.卷积神经网络基础 知识点记录: 神经网络的基础概念主要是:卷积层.池化层,并解释填充.步幅.输入通道和输出通道之含义. 二维卷积层: 常用于处理图像数据,将输入和卷积核做互相关运算,并加上一个标量 ...

  2. windows下pycharm输入法跟随设置

    参考网址:http://www.itdaan.com/blog/2018/05/20/90e64dae077f8ad7fa70bc9c3c8ab422.html

  3. ArcGIS10:ArcGIS version not specified. You must call RuntimeManager.Bind before creating any ArcGIS

    [网络转载] 今天将ArcGIS系列的软件从ArcGIS9.3.1升级到ArcGIS10,然后就使用VS创建一个简单的AE应用程序,然后拖放一个toolbar.LicenseControl以及MapC ...

  4. css样式读取

    在做页面改写时,发现外部引入的样式表中一部分的样式起作用,另一部分的样式没有用.无论怎么修改都没有用.最后搜索了下答案,发现是css样式文件与需引入的文件编码不一致.导致样式读取不到或者读取到一半.

  5. bbs论坛注册功能(1)

    分析项目需求创建表: STATICFILE_DIR = [ os.path.join(BASE_DIR,'static') #设置目录,bootstrip添加到目录中去,直接本地调用 ] # auth ...

  6. 如何转proto

    找到对应协议在对应proto中的片段(片段的子也要提取),提出来 放到适合proto文件中(逻辑 || 功能近似协议聚集地) 转换成proto.js 替换 || 增加原有js内容

  7. C++-CodeForces-1307A/1307B/1307C

    假装自己打比赛嘿嘿嘿 #include <bits/stdc++.h> using namespace std; ]; int main(){ for(cin>>t;t--;) ...

  8. http断点续传的原理

    ——————————————先讲原理,如下:—————————————————— 举一个详细的例子: 一般场景,要访问的域名:www.jizhuomi.com/android,文件名为down.zip ...

  9. linux 内存,cpu占用最高进程查询

    1. 可以使用一下命令查使用内存最多的10个进程 ps -aux | sort -k4nr | head -n 10 2. 可以使用一下命令查使用CPU最多的10个进程 ps -aux | sort ...

  10. redis解决方案之三种集群模式的概念与部署

    上篇文章为大家总结了redis命令并讲述了持久化,今天我们来看一下redis的三种集群模式:主从复制,哨兵集群,Cluster集群 本篇文章先介绍redis-cluster集群模式,然后再依次介绍它的 ...