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,一经查实,立即删除!

相关文章

ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao

package org.dao;import java.util.List;import org.entity.Dept;/*** * * 项目名称&#xff1a;test_ssm_16qn3 * 类名称&#xff1a;IDeptDao * 类描述&#xff1a; 部门表的接口 * 创建人&#xff1a;Mu Xiongxiong * 创建时间&#xff1a;2017-12-26 下午8:…

Spring 基于设值函数的依赖注入

Spring 基于设值函数的依赖注入 当容器调用一个无参的构造函数或一个无参的静态 factory 方法来初始化你的 bean 后&#xff0c;通过容器在你的 bean 上调用设值函数&#xff0c;基于设值函数的 DI 就完成了。 示例&#xff1a; 下述例子显示了一个类 TextEditor&#xff0c…

[SSCore] 开源dotnet core 版本 SuperSocket

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

字母图形

资源限制 时间限制&#xff1a;1.0s 内存限制&#xff1a;256.0MB 问题描述 利用字母可以组成一些美丽的图形&#xff0c;下面给出了一个例子&#xff1a; ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 这是一个5行7列的图形&#xff0c;请找出这个图形的规律&#xff0c;并…

Spring 注入内部 Beans

转载自 Spring 注入内部 Beans 注入内部 Beans 正如你所知道的 Java 内部类是在其他类的范围内被定义的&#xff0c;同理&#xff0c;inner beans 是在其他 bean 的范围内定义的 bean。因此在 或 元素内 元素被称为内部bean&#xff0c;如下所示。 <?xml version"…

asp.net core mvc剖析:KestrelServer

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

ssm(Spring+Spring mvc+mybatis)Dao层实现类——DeptDaoImpl

/** * Title: DeptDaoImpl.java * Package org.dao.impl * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-12-26 下午9:02:32 * version V1.0 */ package org.dao.impl;import java.util.List;import org.dao.IDeptDao…

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;//存储图对应的…

Spring 注入集合

转载自 Spring 注入集合 注入集合 你已经看到了如何使用 value 属性来配置基本数据类型和在你的 bean 配置文件中使用<property>标签的 ref 属性来配置对象引用。这两种情况下处理奇异值传递给一个 bean。 现在如果你想传递多个值&#xff0c;如 Java Collection 类…

.net core依赖注入的封装

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

ssm(Spring+Spring mvc+mybatis)Dao层配置sql的文件——DeptDaoMapper.xml

<?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- namespace&#xff1a;接口的全路径名 --> <map…

图的深度优先遍历+图解

图解 代码实现 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;//存储图对应的邻接矩阵…

php mysql 编码为utf-8_php连mysql用 utf-8编码乱码怎么办

展开全部PHP页面转UTF-8编码问32313133353236313431303231363533e78988e69d8331333361316639题1.在代码开始出加入一行&#xff1a;复制代码 代码如下:header("Content-Type:text/html;charsetutf-8");2.PHP文件编码问题点击编辑器的菜单&#xff1a;“文件”->“…

Spring 自动装配 ‘byName’

转载自 Spring 自动装配 ‘byName’ Spring 自动装配 ‘byName’ 这种模式由属性名称指定自动装配。Spring 容器看作 beans&#xff0c;在 XML 配置文件中 beans 的 auto-wire 属性设置为 byName。然后&#xff0c;它尝试将它的属性与配置文件中定义为相同名称的 beans 进行…

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

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

ssm(Spring+Spring mvc+mybatis)Service层接口——IDeptService

/** * Title: IDeptService.java * Package org.service * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-12-26 下午9:10:12 * version V1.0 */ package org.service;import org.dao.IDeptDao;/** * * 项目名称&…

centos5.9 mysql_CentOS 5.9系统服务器使用yum安装Apache+PHP+MySQL环境

Centos 里的 yum 在线安装很慢.以下是替换为中国CentOS镜像服务器!中国官方镜像网站: http://centos.ustc.edu.cn//* 使用说明 */cd /etc/yum.repos.d[进入yum.repos.d目录]mv CentOS-Base.repo CentOS-Base.repo.save[修改源文件名称备份]wget http://centos.ustc.edu.cn/Cent…

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

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

Spring 自动装配 ‘byType’

转载自 Spring 自动装配 ‘byType’ Spring 自动装配 ‘byType’ 这种模式由属性类型指定自动装配。Spring 容器看作 beans&#xff0c;在 XML 配置文件中 beans 的 autowire 属性设置为 byType。然后&#xff0c;如果它的 type 恰好与配置文件中 beans 名称中的一个相匹配…