首页 > 编程语言 >Java数据结构与算法(平衡二叉树)

Java数据结构与算法(平衡二叉树)

时间:2024-05-25 17:02:36浏览次数:19  
标签:node right Java AVLTreeNode 二叉树 key 平衡 数据结构 left

前言

平衡二叉树是为了提高二叉树的查询速度,通过满足特定的条件来保持其平衡性。平衡二叉树具有以下特点:

  • 左子树和右子树的高度差不会大于1,这是为了确保树的高度不会过大,从而减少查询时的磁盘I/O开销,提高查询速度。
  • 平衡二叉树上的所有结点的平衡因子(左子树深度减去右子树深度的值)只可能是-1、0和1。这表示树处于平衡状态,没有明显的倾斜。
  • 当插入或删除一个结点后,如果破坏了树的平衡性,需要进行相应的旋转操作来调整,以恢复平衡。这包括左旋转和右旋转两种操作。

平衡二叉树的实现原理基于二叉排序树,在构建过程中,每当插入一个结点时,都会检查是否因插入而破坏了树的平衡性。如果破坏了,则找出最小不平衡子树,并在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

通过这样的机制,平衡二叉树能够有效地保持其结构的平衡,从而在插入、删除和查找等操作中保持较高的效率。

实现原理

平衡二叉树实现的概述:

  1. 节点结构:定义节点的结构,包括键值、父节点、左右子节点以及树的高度。
  2. 插入操作:
    • 插入一个节点时,首先更新该节点的父节点信息和高度信息。
    • 检查树的平衡性是否被破坏,即节点的平衡因子(左右子树高度差)的绝对值是否大于1。
    • 如果平衡被破坏,找到最小不平衡子树,并进行旋转操作,以恢复树的平衡。
  3. 删除操作:
    • 删除一个节点时,首先更新该节点的父节点信息和高度信息。
    • 检查树的平衡性是否被破坏,即节点的平衡因子(左右子树高度)的绝对值是否大于1。
    • 如果平衡被破坏,找到最小不平衡子树,并进行旋转操作,以恢复树的平衡。
  4. 查找操作:在树中进行查找操作,利用二叉搜索树的特性进行快速查找。

具体代码实现

class AVLTreeNode {
    int key;
    int height;
    AVLTreeNode left;
    AVLTreeNode right;
 
    AVLTreeNode(int key) {
        this.key = key;
        this.height = 0;
        this.left = this.right = null;
    }
}
 
public class AVLTree {
 
    private AVLTreeNode root;
 
    public AVLTree() {
        root = null;
    }
 
    // 获取以节点为根的树的高度
    private int height(AVLTreeNode node) {
        if (node == null) {
            return 0;
        }
        return node.height;
    }
 
    // 更新节点的高度
    private void updateHeight(AVLTreeNode node) {
        node.height = Math.max(height(node.left), height(node.right)) + 1;
    }
 
    // 左旋
    private AVLTreeNode rotateLeft(AVLTreeNode node) {
        AVLTreeNode rightNode = node.right;
        node.right = rightNode.left;
        rightNode.left = node;
        updateHeight(node);
        updateHeight(rightNode);
        return rightNode;
    }
 
    // 右旋
    private AVLTreeNode rotateRight(AVLTreeNode node) {
        AVLTreeNode leftNode = node.left;
        node.left = leftNode.right;
        leftNode.right = node;
        updateHeight(node);
        updateHeight(leftNode);
        return leftNode;
    }
 
    // 左右旋(先左后右)
    private AVLTreeNode rotateLR(AVLTreeNode node) {
        node.left = rotateLeft(node.left);
        return rotateRight(node);
    }
 
    // 右左旋(先右后左)
    private AVLTreeNode rotateRL(AVLTreeNode node) {
        node.right = rotateRight(node.right);
        return rotateLeft(node);
    }
 
    // 插入节点
    public void insert(int key) {
        root = insert(root, key);
    }
 
    // 递归插入并平衡
    private AVLTreeNode insert(AVLTreeNode node, int key) {
        if (node == null) {
            return new AVLTreeNode(key);
        }
 
        if (key < node.key) {
            node.left = insert(node.left, key);
            if (height(node.left) - height(node.right) == 2) {
                if (key < node.left.key) {
                    node = rotateRight(node);
                } else {
                    node = rotateLR(node);
                }
            }
        } else if (key > node.key) {
            node.right = insert(node.right, key);
            if (height(node.right) - height(node.left) == 2) {
                if (key > node.right.key) {
                    node = rotateLeft(node);
                } else {
                    node = rotateRL(node);
                }
            }
        }
 
        updateHeight(node);
        return node;
    }
}

QA:待定

标签:node,right,Java,AVLTreeNode,二叉树,key,平衡,数据结构,left
From: https://blog.csdn.net/acuteeagle01/article/details/139193615

相关文章

  • 深入理解ECMAScript:JavaScript的规范与实践
    引言在当今的Web开发领域,JavaScript几乎无处不在。它不仅在客户端编程中占据主导地位,而且在服务器端(Node.js)和移动应用开发中也越来越受欢迎。然而,JavaScript的核心并非由单一的公司或组织控制,而是由一个国际标准组织——ECMAInternational通过ECMAScript规范来定义。本文将......
  • 基于JAVA GUI体育馆管理系统的会员功能
      JavaGUI即Java图形用户界面,是一种使用图形化元素(如窗口、按钮、文本框等)来构建用户界面的技术。它基于Java的Swing框架,可以用于创建各种复杂的用户界面,包括窗口、对话框、菜单、按钮、文本框、复选框、下拉列表等。  JavaGUI具有以下特点:跨平台性:Java是一种跨平台......
  • Java Thread
    Thread一般而言,线程是CPU资源调度的基本单位。在java中,线程通过系统内核线程实现,每个Java线程对应着一个内核线程。以HotSpotJVM为例,它的每一个Java线程都是直接映射到一个操作系统原生线程来实现的,中间没有额外的结构,HotSpot不会干涉线程调度。线程调度全由操作系统去处理,包括......
  • Java 多线程编程 力扣实题
    多线程编程实例了解内存模型、线程通信和线程安全之后,对多线程编程已经有了理论上的认知,现在来实战一下。所有题目在https://leetcode.cn/problemset/concurrency/。按序打印题干描述给你一个类:publicclassFoo{publicvoidfirst(){print("first");}publicvoidseco......
  • Java 多线程编程基础
    我们的应用程序都是运行在多线程的环境下的,在多线程环境下的许多问题我们都了解吗?线程间如何进行数据交换?线程间如何进行通信与协作?共享一个资源时如何保证线程安全?线程数据交换线程之间无法直接访问对方工作内存中的变量,必须通过主内存进行变量的传递。例如,线程A、B共享一......
  • Java ThreadPoolExecutor
    ThreadPoolExecutor?ThreadPoolExecutor是什么,先拆开来看,ThreadPoolAndExecutor?那ThreadPool是什么?Executor又是什么?Executor:任务执行者,只定义了一个execute方法,接收一个Runable参数。publicinterfaceExecutor{voidexecute(Runnablecommand);}ThreadPool:可以缓存......
  • 二叉树前中后序遍历
    前言个人小记一、代码如下#include<stdio.h>#include<stdlib.h>#include<time.h>#defineMAX_NODE10#definep()\{\printf("\n");\}typedefstructNode{intkey;intlfag,rfag;structNode*lchild,*rchild;}Node;......
  • Java实现图书系统
    首先实现一个图书管理系统,我们要知道有哪些元素?1.用户分成为管理员和普通用户2.书:书架  书3.操作的是:书架目录第一步:建包第二步:搭建框架首先:完成book中的方法其次:完成BookList然后:完成管理员界面和普通用户界面最后:Main第三步:细分方法1.退出系统2......
  • 从零手写实现 nginx-01-为什么不能有 java 版本的 nginx?
    前言大家好,我是老马。很高兴遇到你。作为一个java开发者,工作中一直在使用nginx。却发现一直停留在使用层面,无法深入理解。有一天我在想,为什么不能有一个java版本的nginx呢?一者是理解nginx的设计灵魂,再者java开发者用java语言的服务器不是更加自然吗。于是动手开......
  • arthas:Java调试利器,线上Debug不是梦
    目录前言一、Arthas是什么?二、Arthas能解决啥问题?三、Arthas两种安装、启动方式1、jar包启动2、在线安装3、远程连接:四、Arthas命令使用1、Dashboard命令2、Thread(线程监控)3、JVM(jvm实时运行状态,内存使用情况等)4、trace(当前方法内部调用路径,路径上每个节......