java平衡二叉树AVL数
平衡二叉树(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数的更多相关文章
- Java 树结构实际应用 四(平衡二叉树/AVL树)
平衡二叉树(AVL 树) 1 看一个案例(说明二叉排序树可能的问题) 给你一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在. 左边 BST 存在的问题分析: ...
- 数据结构与算法--从平衡二叉树(AVL)到红黑树
数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树.算法的性能取决于树的形状,而树的形状取决于插入键的顺序.在最好的情况下,n个结点的树是完全平衡的,如下图"最好情况&q ...
- 二叉查找树、平衡二叉树(AVL)、B+树、联合索引
1. [定义] 二叉排序树(二拆查找树)中,左子树都比节点小,右子树都比节点大,递归定义. [性能] 二叉排序树的性能取决于二叉树的层数 最好的情况是 O(logn),存在于完全二叉排序树情况下,其访 ...
- Java中的数是用补码表示的检验
一.基本介绍(关于下列五个定义来自http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html#!comments,谢原 ...
- 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)
二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...
- 【Java】PS-查看Java进程-线程数
PS-查看Java进程-线程数 ps 线程 个数_百度搜索 查看进程的线程数命令 - CSDN博客 java命令行运行jar里的main类 - coderland - 博客园
- 平衡二叉树AVL - 插入节点后旋转方法分析
平衡二叉树 AVL( 发明者为Adel'son-Vel'skii 和 Landis)是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1. 首先我们知道,当插入一个节点,从此插入点到树根 ...
- JAVA把毫秒数转换成日期
JAVA把毫秒数转换成日期 systemMillonSenconds = System.currentTimeMillis(); 2012-08-17 14:42 1456人阅读 评论(1) 收藏 ...
- java代码行数统计工具类
package com.syl.demo.test; import java.io.*; /** * java代码行数统计工具类 * Created by 孙义朗 on 2017/11/17 0017 ...
随机推荐
- 转载:android audio policy
Audio policy basic:https://www.cnblogs.com/CoderTian/p/5705742.html Set volume flow:https://blog.csd ...
- SSM-整合简单配置
首先说明Spring和Mybatis的版本: Spring:3.2.4 Mybatis:3.3.0 使用了C3P0连接池和Log4J日志,下面是jar包总览: 然后是项目目录总览: 为了能够让项目跑一 ...
- SSM项目中的.tld文件是什么,有什么作用?怎么自定义tld文件
原文链接:https://www.cnblogs.com/guaishoubiubiu/p/8721277.html TLD术语解释:标签库描述文件,如要在JSP页面中使用自定义JSP标签,必须首先定 ...
- 优酷1080p的kux格式文件转码
@echo off for /r . %%i in (*.kux) do ( "C:\Program Files (x86)\YouKu\YoukuClient\nplayer\ffmpeg ...
- jQuery 扩展 全屏切换
(function ($) { //全屏切换方法 $.fn.toggleFullScreen = function (qp1, qp2) { var fullFlag = false; var _qp ...
- Python3标准库:textwrap文本自动换行与填充
1. textwrap文本自动换行与填充 textwrap模块提供了一些快捷函数,以及可以完成所有工作的类TextWrapper.如果你只是要对一两个文本字符串进行自动或填充,快捷函数应该就够用了:否 ...
- opencv学习之颜色空间转换cvtColor()
我们生活中大多数看到的彩色图片都是RGB类型,但是在进行图像处理时,需要用到灰度图.二值图.HSV.HSI等颜色制式,opencv提供了cvtColor()函数来实现这些功能.首先看一下cvtColo ...
- HTML5-语义化
什么是语义化?就是用合理.正确的标签来展示内容,比如h1~h6定义标题. 语义化优点: 易于用户阅读,样式丢失的时候能让页面呈现清晰的结构. 有利于SEO,搜索引擎根据标签来确定上下文和各个关键字的权 ...
- crontab实践
1.crontab概要 2.crontab使用 3.关键配置信息 3.1如何配置定时任务 4.注意事项 参考 https://www.cnblogs.com/keithtt/p/6946498.htm ...
- RHEL7忘记密码:修改root密码
博客链接:http://blog.csdn.net/derkampf/article/details/54346516 问题描述:日常工作和使用红帽子7系统时,容易发生忘记密码(root)这种尴尬的情 ...