JAVA之查找二叉平衡树

平衡二叉树建立及其增删改查(JAVA) 平衡二叉树:指的是左右子树高度差的绝对值不超过一的二叉排序树。 主要思路:1、用左高度跟右高度代替平衡因子,大于1进行L~调整,小于-1进行R~调整                   2、每次插入都通过递归计算一次各结点高度,然后进行旋转调整                   3、判断旋转操作时只需判断从失衡节点开始前两个节点  LL:左左左  、 RR:右右右  、 LR:左右~  、... 阅读详情

查找二叉平衡树与查找二叉树有什么区别呢?当要进行大规模删除操作时(先不考虑懒惰删除),会出现某种情况,高度会逐渐的变大,是因为我们总是把右边最小的叶子节点变为删除的点,再去删除右边最大的点,这就导致了高度变大,查找数据时间变长,显然这是要优化的。

  1. 我们需要在Node(内部节点类)中加入一个高度height的一个变量
  2. 思想:当插入的时候左节点和右节点的高度度相差深度超过1的时候,必须要旋转相应的节点来保持高度的平衡。
  3. 分为4种情况
    对于平衡二叉树有4中情况
    * 1.对&的左儿子的左子树进行一次插入
    * 2.对&的左儿子的右子树进行一次插入
    * 3.对&的右儿子的左子树进行一次插入
    * 4.对&的右儿子的右子树进行一次插入
package tree;


/*
    平衡查找二叉树
         * 对于平衡二叉树有4中情况
         * 1.对&的左儿子的左子树进行一次插入
         * 2.对&的左儿子的右子树进行一次插入
         * 3.对&的右儿子的左子树进行一次插入
         * 4.对&的右儿子的右子树进行一次插入
 */
public class AVLTree<AnyType extends Comparable<? super AnyType>>{
    /*
     * 节点内部类
     */
    private static class AvlNode<AnyType>{
        AnyType         element;    //数据(data)
        AvlNode<AnyType> left;      //左节点(Left child)
        AvlNode<AnyType> right;     //右节点(right child)
        int             height;     //高度(height)
        public AvlNode(AnyType x){
            this(x, null, null);
        }
        public AvlNode(AnyType theElement, AvlNode<AnyType> lt, AvlNode<AnyType> rt){
            element = theElement;
            left = lt;
            right = rt;
        }
    }

    private AvlNode<AnyType> root;  //根节点
    //初始化操作
    public AVLTree(){
        root = null;
    }
    //判断是否为空树
    public boolean isEmpty(){
        return root == null;
    }
    //直接清空树
    public void makeEmpty(){
        root = null;
    }
    /*
     * 添加节点
     */
    public void insert(AnyType x){
        root =  insert(x, root);
    }

    /*
     *      前面的插入和ADT树没多大的区别,最大的区别就在于当插入数据的时候要先检查插入的数据相对的高度差
     *      如果差值大于1,那么就要对应的进行旋转
     */
    private AvlNode<AnyType> insert(AnyType x, AvlNode<AnyType> t){
        if(t == null)
            return new AvlNode(x ,null, null);

        int compareResult = x.compareTo(t.element); //比较当前节点的大小

        if(compareResult > 0)
            t.right = insert(x, t.right);
        else if(compareResult < 0)
            t.left = insert(x, t.left);
        else
            ;
        return balanced(t);
    }

    private static final int ALLOWED_IMBALANCE = 1;

    private AvlNode<AnyType> balanced(AvlNode<AnyType> t){
        if(t == null)
            return t;

        if(height(t.left) - height(t.right) > ALLOWED_IMBALANCE)
            if(height(t.left.left) >= height(t.left.right))
                t = rotateWithLeftChild(t);
            else
                t = doubleWithLeftChild(t);
        else if(height(t.right) - height(t.left) > ALLOWED_IMBALANCE)
            if(height(t.right.right) > height(t.right.left))
                t = rotateWithRightChild(t);
            else
                t = doubleWithRightChild(t);

        t.height = Math.max(height(t.left), height(t.right)) + 1;
        return t;
    }

    /*
     * 每个节点的高度情况    只有三种情况 0    1   -1
     */
    private int height(AvlNode<AnyType> t){
        return t == null ? -1 : t.height; 
    }

    /*
     * 第一种情况:对&的左儿子的左子树进行一次插入(单旋转)
                    k2                      k1
                k1      z       --->    x       k2  
              x    y                          y    z    
     */
    private AvlNode<AnyType> rotateWithLeftChild(AvlNode<AnyType> k2){
        AvlNode<AnyType> k1 = k2.left;
        k2.left = k1.right;     //k2的左子树等于k1的右子树
        k1.right = k2;

        k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
        k1.height = Math.max(height(k1.left), k2.height) + 1;
        return k1;
    }

    /*
     * 第二种情况:对&的左儿子的右子树进行一次插入(双旋转)
     *          k3                          k2
     *    k1         d      --->        k1      k3
     * a      k2                      a   b    c   d
     *      b    c
     */
    private AvlNode<AnyType> doubleWithLeftChild(AvlNode<AnyType> k3){
        k3.left = rotateWithLeftChild(k3.left);
        return rotateWithLeftChild(k3);
    }
    /*
     * 第三种情况:对&的右儿子的左子树进行一次插入(单旋转)
                    k2                          k1
                z       k1          --->    k2      y
                      x    y              z   x
     */
    private AvlNode<AnyType> rotateWithRightChild(AvlNode<AnyType> k2){
        AvlNode<AnyType> k1 = k2.right;
        k2.right = k1.left;     //k2的左子树等于k1的右子树
        k1.left = k2;

        k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
        k1.height = Math.max(height(k1.right), k2.height) + 1;
        return k1;
    }
    /*
     * 第四种情况:对&的右儿子的右子树进行一次插入(双旋转)
     */
    private AvlNode<AnyType> doubleWithRightChild(AvlNode<AnyType> k3){
        k3.right = rotateWithRightChild(k3.right);
        return rotateWithRightChild(k3);
    }

    /*
     * 同样,删除操作是最麻烦的操作,当删除一个节点的时候,也有可能会造成树的不平衡,
     * 所以也要调用balanced方法
     */
    public void remove(AnyType x){
        remove(x, root);
    }

    private AvlNode<AnyType> remove(AnyType x, AvlNode<AnyType> t){
        if(t == null)
            return t;

        int compareResult = x.compareTo(t.element);

        if(compareResult < 0)
            t.left = remove(x, t.left);
        else if(compareResult > 0)
            t.right = remove(x, t.right);
        else if (t.left != null && t.right != null){
            t.element = findMin(t.right).element;
            t.right = remove(t.element, t.right);
        }else
            t = (t.left != null) ? t.left : t.right;
        return balanced(t);
    }

    /*
     * 取树中的最小值(一直找左子树就ok)
     */
    public AnyType findMin(){
        if(isEmpty())
            throw new NullPointerException();
        return findMin(root).element;
    }
    private AvlNode<AnyType> findMin(AvlNode<AnyType> t){
        if(t == null)
            return null;
        else if(t.left == null)
            return t;
        return findMin(t.left);
    }
    /*
     * 去树中的最大值(一直找右子树)
     */
    public AnyType findMax(){
        if(isEmpty())
            throw new NullPointerException();
        return findMax(root).element;
    }
    private AvlNode<AnyType> findMax(AvlNode<AnyType> t){
        if(t == null)
            return null;
        else if(t.right == null)
            return t;
        return findMax(t.right);
    }

    public void printTree(){
        if(isEmpty())
            System.out.println("空树");
        else
            printTree(root);
    }

    private void printTree(AvlNode<AnyType> t){
        if(t != null){
            System.out.println("值:" + t.element+" " + ",高度:" + t.height);
            printTree(t.left);
            printTree(t.right);
        }
    }
    public static void main(String[] args){
        AVLTree<Integer> bst = new AVLTree<>();
        bst.insert(1);
        bst.insert(2);
        bst.insert(3);
        bst.insert(4);
        bst.insert(5);
        bst.insert(6);
        bst.printTree();
        System.out.println("最小值:" + bst.findMin());
    }
}
51单片机嵌入式开发:14、STC89C52RC 之HX1838红外解码NEC+数码管+串口打印+LED显示 对于C51单片机的设计思路,你可以使用类似的步骤来实现红外解码、数码管显示和LED显示的功能。下面是一个简单的设计思路:(1) 连接HX1838红外解码器、数码管和LED到C51单片机。将HX1838的信号引脚连接到C51单片机的外部中断引脚(例如INT0),数码管的CLK引脚连接到C51单片机的某个IO口引脚,数码管的DIO引脚连接到C51单片机的另一个IO口引脚,LED连接到C51单片机的某个IO口引脚。(2) 在C51的程序中,定义并初始化所需的IO口和外部中断。 阅读详情

相关推荐

MaxEnt软件的下载与安装

1、下载网站:http://lucky-boy.ys168.com/ (这是之前在网上搜到的,里面有许多软件安装包,感谢网页主的资源共享,违权必删)

weixin_42191203的博客 2万+

Java 二叉平衡树高度解法

废话少说,直接上代码 import java.util.LinkedList; /** * @author hehe * @version : TreeHeight.java, v 0.1 2019-10-10 19:52 */ public class TreeHeight { static class TreeNode{ int val; T...

haochajin的博客 241

科研党必备:用MATLAB批量处理.mat文件数据的3种高效方法

本文为科研人员提供了使用MATLAB批量处理.mat文件数据的三种高效方法,涵盖智能数据加载、专业可视化与自动化报告生成。通过构建自动化框架、多维度数据画图策略及批量处理流程,帮助用户显著提升数据处理效率与图表专业性,解决海量实验数据的管理与分析难题。

weixin_29089057的博客 71

AVL树

AVL树:是带有平衡条件的二叉查找树,且左右子节点的树深度相差不超过1;在插入元素的时候可能会破坏原来AVL树的平衡,此时就需要通过旋转来解决平衡问题.在插入以后,只有那些从插入点到根节点的路径上的节点的平衡可能被破坏,因为只有这些节点的子树可能发生变化.所以当我们沿着这条路径上行并更新平衡信息时,可以发现一个节点,它的平衡破坏了AVL条件.此时将第一个这样的节点称为α,插入情况如下: ①.对α

_Snails_ 1017

CRISPR筛选全流程指南:从文库构建到数据分析实战

功能基因组学研究需要高效解析基因型与表型的关联,高通量筛选技术是其中的关键工具。基于CRISPR系统的筛选方法通过大规模sgRNA文库扰动基因功能,结合慢病毒递送和测序分析,能够系统鉴定影响细胞增殖、耐药、病毒感染的候选基因。与RNAi或化学小分子筛选相比,CRISPR筛选具有覆盖全基因组、脱靶率低、信号清晰等优势,已广泛应用于药物靶点发现、合成致死和免疫治疗机制研究。本文围绕实验设计与操作中的核心要点展开,涵盖文库扩增、病毒滴度控制、MOI把握、筛选模式选择以及基于MAGeCK的sgRNA丰度分析,并针对

weixin_31188927的博客 276

GEOPHYSICS 投稿避坑指南:从格式规范到双盲评审的实战解析

本文详细解析了GEOPHYSICS期刊投稿的全流程避坑指南,从格式规范、数据声明到双盲评审的实战策略。特别强调了数学公式排版、图表制作标准以及投稿系统的隐藏关卡,帮助作者避免常见错误,提升投稿成功率。

weixin_30606461的博客 236

平衡二叉树 java_树——平衡二叉树插入和查找的JAVA实现

packagecom.tomsnail.data.tree;/*** AVL二叉平衡树*@authortomsnail* @date 2015年3月30日 下午4:35:50*/public classAVLTree {/*** 根节点*@authortomsnail* @date 2015年3月30日 下午4:36:54*/privateAVLNode rootNode;private Stri...

weixin_36106506的博客 164

思必驰离线语音芯片:智能家居控制的核心引擎

思必驰离线语音芯片TH1520通过本地化语音识别技术,为智能家居带来革命性体验。该芯片具备200-600毫秒的快速响应、75分贝抗噪能力和双核异构设计,显著提升设备交互效率。支持自定义指令和10种音色选择,开发周期缩短至3天,BOM成本降低30%,是智能家居控制的核心引擎。

redis7keeper的博客 985

avl树的插入(含单旋转,双旋转)

学习中写的,所以注释少,结构杂乱,难免有不足之处,望批评改正。如有需要笔者解释的地方,请将问题发到笔者邮箱(lixding@163.com)。 public class AVLTreeClass >{      //节点类 public static class AVLNode{       AnyType data;//数据       AVLNode leftNode;//左子树

u010266352的博客 853

Java对接快递鸟,查询快递物流信息

根据用户输入的订单号,我们的后台识别订单号并根据快递鸟查询快递API接口,实现自动查询的功能。下面是java版本的根据单号查询物流跟踪信息的详细示例代码。只需要下载就可以运行,(自己需要简单的修改)注:登录快递鸟用户管理后台后获得。登录快递鸟用户管理后台。

Roc的博客 957

解锁轻量化网络实验室:在 Containerlab 中部署 Cisco IOL 设备的详细教程

Cisco IOS On Linux(IOL)是 Cisco IOS-XE 的简化版,它是 Cisco IOS 的一种轻量级实现。IOL 并不需要完整的虚拟机(Virtual Machine, VM)环境,可以直接在 Linux 上运行,极大地减少了对系统资源的需求。IOL 节点通过更精简的方式提供了 Cisco IOS 功能,适合构建实验室、测试网络协议和验证网络设计。

网络技术联盟站 476

数据结构 JAVA描述(十五) 动态查找表 二叉排序树 二叉平衡树

二叉排序树 若左子树不空,则左子树上所有结点的值均<根结点的值 若右子树不空,则右子树上所有结点 的值均>根结点的值 它的左、右子树也都是二叉排序树。 二叉排序树的查找过程 若树为空,则结束 若树非空,则进行如下操作若给定值k=根关键字,则查找成功 若给定值<根关键字,则继续在左子树进行 若给定值>根关键字,则继续在右子树进行 二叉排序树的删除过程 若删除的是叶子结点,则直接删除该结点即可。若同时

此生尽兴 863

Android 13.0 开机启动优化之PMS扫描apk耗时相关功能优化

在android13.0的系统rom定制化开发中,在系统中开发产品时,会根据客户要求内置第三方app,这时如果内置app过多,或者安装的app过多,在系统开机的过程中 在pms扫描安装app的时候,就会比较耗时,这时候就需要优化下pms扫描安装app这块的功能代码,用多线程来实现pms扫描安装app,来加快开机时间,接下来 来实现这个功能

安卓兼职framework和app工程师的博客 1333

二叉树实现-java

二叉树的仿真JAVA实现本程序用链表去仿真二叉树查找树与二叉平衡树以下代码用Eclipse3.40编译通过使用的文件清单如下:Node.java    //链结点interfaceSLNode.java    //单向链结点实现类DLNode.java  //双向链结点实现类Strategy.java  //两个数据比较interfaceDefaultStrategy.java //两个数据比较实

移动互联网改变生活,高效配对交易创造财富 1772

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java实现蒙特卡洛树搜索_AVL树(二叉平衡树)java实现与详解

AVL树概念前面学习二叉查找树和二叉树的各种遍历,但是其查找效率不稳定(斜树),而二叉平衡树的用途更多。查找相比稳定很多。(欢迎关注数据结构专栏)AVL树是带有平衡条件的二叉查找树。这个平衡条件必须要容易保持。而且要保证它的深度是O(logN).AVL的条件是左右树的高度差(平衡因子)不大于1;并且它的每个子树也都是平衡二叉树。对于平衡二叉树的最小个数,n0=0;n1=1;nk=n(k-1)+n(...

weixin_42188533的博客 277

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

数据库MySQL-二叉搜索树性能分析:从基础到优化

摘要:本文详细介绍了二叉搜索树(BST)的概念、核心操作与性能分析。BST是一种特殊的二叉树,满足左子树节点值均小于根节点、右子树节点值均大于根节点的性质。文章重点讲解了查找、插入和删除三种核心操作的实现原理,并提供了完整的Java代码实现。性能分析表明,BST在最好和平均情况下的时间复杂度为O(logn),但在最坏情况下会退化为链表,时间复杂度降为O(n)。为此,文章引出二叉平衡树的概念作为改进方案。最后给出了可直接运行的完整Java实现,包含中序遍历演示。

道冲而用之或不盈,渊兮似万物之宗。 946

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

CodeForces 1042D 解题

题目大意: 给你N个数字,和一个数字t,求满足l&lt;=r,a[l] + a[l+1] + …… + a[r] &lt; t 的(l,r)对数。   思路 首先考虑a[l] + a[l+1] + …… + a[r]应该用sum[r] - sum[l - 1]直接求得,那么对于每一个sum[i],我们要求的就是sum[j] &gt; sum[i] - t (1 &lt;= j &lt;= ...

AngrySword的博客 469

java中的树_java回顾之树

java回顾之树一、计算机中的树 1.2、二叉树如果书中的每个节点的子节点的个数不超过2,那么该树就是一个二叉树1.3二叉查找树1、左子树上所有的节点的值均小于他的父节点的值2、右子树上所有的节点值均大于他的父节点的值3、每一个子节点最多有两个子树二叉查找树的排序:按照左中右的方式就能够获取到从小到大排列的元素。1.4二叉平衡树二叉平衡树是一种特殊的二叉查找树,二叉平衡树最高高度和最低高度高度差绝...

weixin_31721961的博客 499

数据结构与算法——AVL树的学习与java实现

二叉平衡树 二叉平衡树又叫做AVL树,它继承了二叉搜索树的规则。 且每个节点的左子树和右子树的高度差最多差1。 二叉平衡树由于不会产生像二叉搜索树那样的极端情况,所以查找,删除(懒惰删除)的时间复杂度为o(logn)。插入操作需要对树作出调整,所以时间复杂度略高于o(logn)。 如下图所示:第一张图为AVL树,第二张图则不是AVL树 AVL树的旋转 插入操作需要满足AVL树的特性:每个节点的...

l118 326

红黑树学习笔记

一种用红色和黑色标记结点的二叉自平衡查找树。

qq_42291035的博客 806

java--集合2---泛型、二叉树、TreeSet

泛型 <>:在不知道传入什么类型参数的时候,使用泛型 1、泛型接口 interface Inter<T>{ public abstract void show(T t); } 实现接口可以继续将参数设置成泛型,然后在创建实现类的时候确定参数类型 也可以直接确定参数类型 2、泛型类 class A<T>{ private T t; } //在创建类对象的时候确定参数类型 3、泛型方法 public static <T> void show(T t

qq_45653018的博客 197

秋招八股--数据结构-基础知识

秋招八股--数据结构-基础知识

weixin_41171614的博客 1936

Java 数据结构指南:二叉树、二叉查找树、平衡树与红黑树

二叉树、二叉查找树、平衡树与红黑树的详解

qq_56323274的博客 670

集合TreeMap 实现原理探究

一、基本概念 在介绍TreeMap之前,我们来了解一种数据结构:二叉树。相信学过数据结构的同学知道,这种结构的数据存储形式在查找的时候效率非常高。 二叉树结构又可再细分为二叉查找树和二叉平衡树 二叉查找树是一种有序的树,所有的左孩子的value值都是小于叶子结点的value值的,所有右孩子的value值都是大于叶子结点的。这样做的好处在于:如果需要按照键值查找数据元素,只要比较当前结点的value值即可(小于当前结点value值的,往左走,否则往右走),这种方式,每次可以减少一半的操作..

Ronin_88的博客 326

数据库底层结构红黑树-二叉树-B树

数据库底层结构红黑树-二叉树-B树 待会总结 先看学习资料 学习网址:https://blog.youkuaiyun.com/h3243212/article/details/52819734

zengxianglei的博客--手指星辰 奈何天! 2033

二叉平衡树(AVL树)Java语言实现

将A的左孩子B向右上旋转代替A成为根结点,将A结点向右下旋转成为B的右子树的根结点,而B的原右子树则作为A结点的左子树。将A的右孩子B向左上旋转代替A成为根结点,将A结点向左下旋转成为B的左子树的根结点,而B的原左子树则作为A结点的右子树。先将A结点的左孩子B的右子树的根结点C向左上旋转提升到B结点的位置,然后再把该C结点向右上旋转提升到A结点的位置。先将A结点的右孩子B的左子树的根结点C向右上旋转提升到B结点的位置,然后再把该C结点向左上旋转提升到A结点的位置。)时间,因为AVL树总是保持平衡的。

锟斤拷 1043
上一篇: 利用动态规划和递归分别求两个串的最大公共子序列
下一篇: JAVA之伸展树
LuFei_java
博客等级 码龄10年 1粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值