AVL树双旋转+图解

图解

在这里插入图片描述

代码实现

package com.atguigu.avl;
/*** @创建人 wdl* @创建时间 2021/3/30* @描述*/
public class AVLTreeDemo {public static void main(String[] args) {
//        int[] arr={4,3,6,5,7,8};//创建一个AVLTree对象
//        int arr[]={10,12,8,9,7,6};int[] arr={10,11,7,6,8,9};AVLTree avlTree = new AVLTree();//添加for (int i = 0; i < arr.length; i++) {avlTree.add(new Node(arr[i]));}//遍历System.out.println("中序遍历");avlTree.infixOrder();System.out.println("在平衡处理后");System.out.println(avlTree.getRoot().height());System.out.println(avlTree.getRoot().leftHeight());System.out.println(avlTree.getRoot().rightHeight());System.out.println("当前的根节点"+avlTree.getRoot());}
}//创建AVLTree
class AVLTree{private Node root;public Node getRoot() {return root;}//查找要 删除的节点public Node search(int value){if (root==null){return null;}else {return root.search(value);}}//查找父节点public Node searchParent(int value){if (root==null){return null;}else {return root.searchParent(value);}}//编写方法//1.返回的是以node为根节点的二叉排序树的最小节点的值//2.删除以node为根节点的二叉排序树的最小节点/**** @param node 传入的节点(当做一颗二叉排序树的根节点)* @return 返回的是以node为根节点的二叉排序树的最小节点的值*/public int delRightTreeMin(Node node){Node target=node;//循环的查找左节点,就会找到最小值while (target.left!=null){target=target.left;}//这时target就指向了最小节点//删除最小节点delNode(target.value);return target.value;}//删除节点public void delNode(int value){if(root==null){return;}else {//1.需求先找到要删除节点targetNodeNode targetNode = search(value);//如果没有找到要删除的节点if(targetNode==null){return;}//如果我们发现targetNode没有父节点//如果们发现当前这颗二叉排序树只有一个节点if (root.left==null&&root.right==null){root=null;return;}//去找到targetNode的父节点Node parent = searchParent(value);//如果要删除的节点是叶子节点if(targetNode.left==null&&targetNode.right==null){//判断targetNode是父节点的左子节点,还是右子节点if (parent.left!=null&&parent.left.value==value){//是左子节点parent.left=null;}else if (parent.right!=null&&parent.right.value==value){//是右子节点parent.right=null;}}else if(targetNode.left!=null&&targetNode.right!=null){//删除有两颗子树的节点int minVal=delRightTreeMin(targetNode.right);targetNode.value=minVal;}else {//删除只有一颗子树的节点//如果要要删除的节点有左子节点if (targetNode.left!=null){if(parent!=null){if (parent.left.value==value){//是左子节点parent.left=targetNode.left;}else{//是右子节点parent.right=targetNode.left;}}else {root=targetNode.left;}}else{ //如果要要删除的节点有右子节点if (parent!=null){if (parent.left.value==value){//是左子节点parent.left=targetNode.right;}else{//是右子节点parent.right=targetNode.right;}}else {root=targetNode.right;}}}}}//添加节点的方法public void add(Node node){if(root==null){root=node;//如果root为空直接让root指向node}else {root.add(node);}}//中序遍历public void infixOrder(){if(root!=null){root.infixOrder();}else {System.out.println("二叉排序树为空,不能遍历");}}}//创建Node节点
class Node{int value;Node left;Node right;public Node(int value) {this.value = value;}//返回左子树的高度public int leftHeight(){if(left==null){return 0;}return left.height();}//返回右子树的高度public int rightHeight(){if(right==null){return 0;}return right.height();}//返回当前节点的高度,以该节点为根节点的树的高度public int height(){return Math.max(left==null?0:left.height(),right==null?0:right.height())+1;}//左旋转方法private void leftRotate(){//创建新的节点,以当前根节点的值Node newNode = new Node(value);//把新的节点的左子树设置成当前节点的左子树newNode.left=left;//把新的节点的右子树设置成当前节点的右子树的左子树newNode.right=right.left;//把当前节点的值替换成右子节点的值value=right.value;//把当前节点的右子树设置成右子树的右子树right=right.right;//把当前节点的左子树(左子节点)设置成新的节点left=newNode;}//右旋转private void rightRotate(){Node newNode = new Node(value);newNode.right=right;newNode.left=left.right;value=left.value;left=left.left;right=newNode;}//查找要删除的节点/**** @param value 希望删除的节点的值* @return 如果找到返回该节点,否则返回null*/public Node search(int value){if(value==this.value){//找到就是该节点return this;}else if (value<this.value){//如果查找的值小于当前节点,向左子树递归查找//如果左子节点为空if(this.left==null){return null;}return this.left.search(value);}else {//如果查找的值不小于当前节点,向右子树递归查找//如果右子节点为空if(this.right==null){return null;}return this.right.search(value);}}//查找要删除节点的父节点/**** @param value 要找到的节点的值* @return 返回的是要删除节点的父节点,如果没有就返回null*/public Node searchParent(int value){//如果当前节点就是要删除的节点的父节点,就返回if((this.left!=null&&this.left.value==value)||(this.right!=null&&this.right.value==value)){return  this;}else {//如果查找的值小于当前节点的值,并且当前节点的左子节点不为空if(value<this.value&&this.left!=null){return this.left.searchParent(value);//向左子树递归查找}else if(value>=this.value&&this.right!=null){return this.right.searchParent(value);//向右子树递归查找}else {return null;//没有找到父节点}}}@Overridepublic String toString() {return "Node{" +"value=" + value +'}';}//添加节点的方法//递归的形式添加节点,注意需要二叉排序树的要求public void add(Node node){if(node==null){return;}//判断传入节点的值,和当前子树的根节点的值得关系if(node.value<this.value){//如果当前节点的左子节点为nullif(this.left==null){this.left=node;}else {//递归的向左子树添加this.left.add(node);}}else {//添加的节点的值大于当前节点的值//如果当前节点的左子节点为nullif(this.right==null){this.right=node;}else {//递归的向右子树添加this.right.add(node);}}//当添加完一个节点后,如果(右子树的高度-左子树的高度)>1,左旋转if (rightHeight()-leftHeight()>1){//如果它的右子树的左子树的高度大于它的右子树的告诉if(right!=null&&right.leftHeight()>right.rightHeight()){//先对当前节点的右节点(右子树)->右旋转right.rightRotate();//再对当前节点进行左旋转leftRotate();}else {//直接进行左旋转即可leftRotate();}return;//必须要!!!}//当添加完一个节点后,如果(左子树的高度-右子树的高度)>1,右旋转if (leftHeight()-rightHeight()>1){//如果它的左子树的右子树的高度大于它的左子树的告诉if(left!=null&&left.rightHeight()>left.leftHeight()){//先对当前节点的左节点(左子树)->左旋转left.leftRotate();//再对当前节点进行右旋转rightRotate();}else {//直接进行右旋转即可rightRotate();}}}//中序遍历public void infixOrder(){if(this.left!=null){this.left.infixOrder();}System.out.println(this);if (this.right!=null){this.right.infixOrder();}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[SSCore] 开源dotnet core 版本 SuperSocket

前言碎语 最近一直在做旧版本dotnet 程序迁移至dotnet core的工作, 非常欣慰dotnet社区的蓬勃发展, 目前大部分的第三方类库或开源代码都有了dotnet core版本 或者可以方便的找到替代方案. 这其中我唯一觉得遗憾的是dotnet 社区大名鼎鼎的socket 通讯框架SuperSocket SuperSock…

asp.net core mvc剖析:KestrelServer

KestrelServer是基于Libuv开发的高性能web服务器&#xff0c;那我们现在就来看一下它是如何工作的。在上一篇文章中提到了Program的Main方法&#xff0c;在这个方法里Build了一个WebHost&#xff0c;我们再来看一下代码&#xff1a; public static void Main( string [] args) …

win 7 mysql 1067_win7系统登陆MySQL服务出现1067错误的解决方法

很多小伙伴都遇到过win7系统登陆MySQL服务出现1067错误的困惑吧&#xff0c;一些朋友看过网上零散的win7系统登陆MySQL服务出现1067错误的处理方法&#xff0c;并没有完完全全明白win7系统登陆MySQL服务出现1067错误是如何解决的&#xff0c;今天小编准备了简单的解决办法&…

图的快速入门

快速入门案例 代码实现 package com.atguigu.graph;import java.util.ArrayList; import java.util.Arrays;/*** 创建人 wdl* 创建时间 2021/4/2* 描述*/ public class Graph {private ArrayList<String> vertexList;//存储顶点集合private int[][] edges;//存储图对应的…

.net core依赖注入的封装

现在流行的系统一般都采用依赖注入的实现方式&#xff0c;利用DI容器来直接获取所用到的类/接口的实例。.net core也一样采用DI的方式&#xff0c;提供了DI容器的接口IServiceCollection&#xff0c;并提供了基于该接口的缺省实现ServiceCollection。 这样我们就可以不再像以前…

图的深度优先遍历+图解

图解 代码实现 package com.atguigu.graph;import java.util.ArrayList; import java.util.Arrays;/*** 创建人 wdl* 创建时间 2021/4/2* 描述*/ public class Graph {private ArrayList<String> vertexList;//存储顶点集合private int[][] edges;//存储图对应的邻接矩阵…

Azure SQL的DTU和eDTU到底是个什么鬼

Azure SQL 使用了数据库事务单位 (DTU) 和弹性数据库事务单位 (eDTU)来作为一个计量单位。 但是DTU和eDTU是什么鬼啊? 官方文档这样解释 DTU 是一个资源度量单位&#xff0c;表示保证可用于单一数据库服务层内特定性能级别的单个 Azure SQL 数据库的资源。 DTU是一定比例的 C…

2015蓝桥杯省赛---java---B---1(三角形面积)

题目 三角形面积 解法 数学方法&#xff0c;直接求三角形的面积 88 - (82)/2 - (46)/2 - (84)/2 64 - (81216) 64 - 36 28 答案 28

深入理解Async/Await

C# 5 Async/Await 语法特性&#xff0c;极大地简化了异步编程&#xff0c;但我们知道&#xff0c;异步编程的基本原理并没有发生根本改变。也就是说&#xff0c;当一些复杂的东西看起来很简单时&#xff0c;它通常意味着有一些有趣的事情在背后发生。在计算机程序设计语言领域&…

2015蓝桥杯省赛---java---B---2(立方变自身)

题目 立方变自身 分析 简单枚举 i^3 99之后&#xff0c;数字越大&#xff0c;数字之和越不可能等于其自身。 代码 package com.atguigu.TEST;public class Demo01 {private static int ans;public static void main(String[] args) { // 6for (int i 1; i < 99; i) {…

【南京】.Net 开源基础服务线下技术交流会

南京地区的.net开发人员对基础服务这块感兴趣的&#xff0c;欢迎大家参加及会后继续交流&#xff0c;踊跃参与&#xff01;若对基础服务相关有深度技术交流的&#xff0c;后续交换联系方式&#xff0c;可一起深度合作。 .NET技术行业落地分享交流会 邀请南京地区.NET技术专家和…

mysql 语句块语法_MySQL ------ MySQL常用语句的语法 (三十四)

MySQL常用的语句语法注意&#xff1a;1、 | 符号用来指出几个选中中的一个&#xff0c;因此NULL | NOT NULL 表示给出null 或 not null2、包含在方括号中的关键字或子句是可选的(如 [like this])3、既没有列出所有的MySQL语句&#xff0c;也没有列出每一条子句和选项4、大写的表…

图的广度优先算法+遍历

图解 代码实现 package com.atguigu.graph;import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList;/*** 创建人 wdl* 创建时间 2021/4/2* 描述*/ public class Graph {private ArrayList<String> vertexList;//存储顶点集合private int[][…

.Net异步编程知多少

1. 引言 最近在学习Abp框架&#xff0c;发现Abp框架的很多Api都提供了同步异步两种写法。异步编程说起来&#xff0c;大家可能都会说异步编程性能好。但好在哪里&#xff0c;引入了什么问题&#xff0c;以及如何使用&#xff0c;想必也未必能答的上来。 自己对异步编程也不是很…

指纹识别开发1.0

在不久之前&#xff0c;用java和C#分别开发了个人脸识别&#xff0c;感觉挺不错的&#xff0c;于是脑袋一发热&#xff0c;想了想能不能搞个指纹识别&#xff0c;答案当然是能&#xff0c;那么问题来了&#xff0c;在人脸识别的时候可以借助自带摄像头提取你的face&#xff0c;…

DFS VS BFS

实际案例 代码实现 package com.atguigu.graph;import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList;/*** 创建人 wdl* 创建时间 2021/4/2* 描述*/ public class Graph {private ArrayList<String> vertexList;//存储顶点集合private in…

CLR运行时细节 - Method Descriptor

方法描述符:MethodDesc 运行时用来描述类型的托管方法,它保存在方法描述桶(MethodDescChunk)内;方法描述符保存了方法在运行时的一些重要信息:是否JIT编译;是否有方法表槽(决定了方法入口是跟在方法描述符(MethodDesc)后还是在方法表(MethodTable)后面);距离MethodDescChunk的索…

2015蓝桥杯省赛---java---B---3(三羊献瑞)

题目 三羊献瑞 思路分析 由于是填空题&#xff0c;没有时间和内存的要求&#xff0c;所以看到这个题&#xff0c;第一想法就是暴力破解&#xff0c;当然了&#xff0c;怎么快就怎么做。 由于 "三"是数字的首位&#xff0c;低位的数字进位后必然为1&#xff0c;所…

mysql common是什么_MySQL common_schema简介

common_schema为MySQL提供了查询脚本&#xff0c;分析并且信息化的视图和一个函数库&#xff0c;以便更容易的管理和诊断。它引入的一些基于SQL的工具简common_schema的简介&#xff1a;Shlomi Noach 的common_schema项目()是一套针对服务器脚本化和管理的强大的代码和视图。co…

数据库权限分配探讨

上周&#xff0c; 有位朋友给我提出了这样的需求&#xff1a;区分用户访问数据库的权限。顺便总结了下有如下要求&#xff1a; 某个用户查询所有数据库的权限 某个用户只有备份数据库的权限 给一个用户只能查看指定数据库的权限 给一个用户只有某个表的权限 要进行以上任务&…