package com.xd.leetcode.shu;

/**
* created by lianzhen on 2020-03-10 10:27. describe:平衡二叉树的构建
*
* LL:插入的结点在左子树的左边导致失衡:右旋(顺时针旋转)
* RR: 插入的结点在右子树的右边导致失衡:左旋(逆时针方向)
* LR:插入的结点在左子树的右边导致失衡:先按照根节点的左子树左旋再按照根节点进行右旋
* RL:插入的结点在右子树的左边导致失衡:先按照根结点的右子树右旋再按照根节点进行左旋
*/
public class AVLTree { class Node {
int data; //数据
int height;//高度
Node leftNode;//左节点
Node rightNode;//右节点 public Node(int data, Node leftNode, Node rightNode) {
this.data = data;
this.leftNode = leftNode;
this.rightNode = rightNode;
}
} //计算每个根节点的高度
private int getHeight(Node tagNode) {
if (tagNode == null) {
return -1;
}
return tagNode.height;
} //右旋转
private Node rightRotation(Node tagNode) {
//找到这个目标节点的左子树的根节点
Node leftChild = tagNode.leftNode;
if (leftChild.rightNode != null) {
//把自己的右子树作为目标节点的左子树
tagNode.leftNode = leftChild.rightNode;
}
//让目标节点成为自己的右子树
leftChild.rightNode = tagNode;
//重新设置高度
tagNode.height = Math.max(getHeight(tagNode.leftNode), getHeight(tagNode.rightNode)) + 1;
leftChild.height = Math.max(getHeight(leftChild.leftNode), getHeight(leftChild.rightNode) + 1);
return leftChild;
} //左旋转
private Node leftRotation(Node tagNode) {
//找到这个目标节点的右子树的根节点
Node rightNode = tagNode.rightNode;
if (rightNode.leftNode != null) {
//把自己的左子树作为目标节点的右子树
tagNode.leftNode = rightNode.leftNode;
}
//让目标节点成为自己的左子树
rightNode.leftNode = tagNode; tagNode.height = Math.max(getHeight(tagNode.leftNode), getHeight(tagNode.rightNode)) + 1;
rightNode.height = Math.max(getHeight(rightNode.leftNode), getHeight(rightNode.rightNode)) + 1;
return rightNode;
} //左右旋转LR
private Node rightLeftRatation(Node tagNode) {
//先按照目标节点的左子树的根节点进行右旋转
Node leftChild = tagNode.leftNode;
leftRotation(leftChild);
//再按照目标节点进行左旋转
return rightRotation(tagNode);
} //右左旋转
private Node leftRightRatation(Node tagNode) {
//先按照目标节点的右子树的根节点进行左旋转
Node rightChild = tagNode.rightNode;
rightRotation(rightChild);
//再按照目标节点进行右旋转
return leftRotation(tagNode);
} /**
* 朝根的节点下方插入新的节点 不需要要考虑那么多 只考虑当前的节点再上一个节点的左边或者右边就行
*
* @param root 根节点
* @param data 需要插入节点的数据
*/
private Node insertNode(Node root, int data) {
if (root == null) {
root = new Node(data, null, null);
}else {
if (data <= root.data) {
//把新的节点放在这个节点的左边
root.leftNode = insertNode(root.leftNode, data);
//判断左右子树的高度
if(getHeight(root.leftNode)-getHeight(root.rightNode)>1){
if(data<=root.leftNode.data){
//插入的位置是左子树的左边 ---进行右旋转
root= rightRotation(root);
}else {
//插入的位置是左子树的右边LR 先左后右旋
root=leftRightRatation(root);
}
} } else {
//把新的节点放在这个节点的右边
root.rightNode = insertNode(root.rightNode, data);
//判断左右子树的高度
if(getHeight(root.rightNode)-getHeight(root.leftNode)>1){
if(data<=root.leftNode.data){
//进行右左旋转
root= rightLeftRatation(root);
}else {
//进行右旋转
root=rightRotation(root);
}
}
}
} //对节点的高度进行更新(有可能不变)
root.height=Math.max(getHeight(root.leftNode),getHeight(root.rightNode))+1;
return root;
} }

AVL树的构建的更多相关文章

  1. 二叉树与AVL树

    二叉树 什么是二叉树? 父节点至多只有两个子树的树形结构成为二叉树.如下图所示,图1不是二叉树,图2是一棵二叉树. 图1 普通的树                                    ...

  2. 数据结构图文解析之:AVL树详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  3. 平衡搜索树(一) AVL树

    AVL树 AVL树又称为高度平衡的二叉搜索树,是1962年有俄罗斯的数学家G.M.Adel'son-Vel'skii和E.M.Landis提出来的.它能保持二叉树的高度 平衡,尽量降低二叉树的高度,减 ...

  4. 数据结构与算法(九):AVL树详细讲解

    数据结构与算法(一):基础简介 数据结构与算法(二):基于数组的实现ArrayList源码彻底分析 数据结构与算法(三):基于链表的实现LinkedList源码彻底分析 数据结构与算法(四):基于哈希 ...

  5. AVL树和平衡二叉树 平衡因子 右旋转LL 左旋转RR LR RL

    前言 今天要介绍几种高级数据结构AVL树,介绍之前AVL,会先说明平衡二叉树,并将树的学习路线进行总结,并介绍维持平衡的方法:右旋转.左旋转. 一.树学习路线 1.路线总结 总结了一下树的学习路线,如 ...

  6. 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)

    二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...

  7. 二叉查找树(BST)、平衡二叉树(AVL树)

    二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点,都满足其左子树上所有结点的数据域均小于或等于根结点的数据域,右 ...

  8. 【Java】 大话数据结构(12) 查找算法(3) (平衡二叉树(AVL树))

    本文根据<大话数据结构>一书及网络资料,实现了Java版的平衡二叉树(AVL树). 平衡二叉树介绍 在上篇博客中所实现的二叉排序树(二叉搜索树),其查找性能取决于二叉排序树的形状,当二叉排 ...

  9. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

  10. AVL树 算法思想与代码实现

    AVL树是高度平衡的二叉搜索树,按照二叉搜索树(Binary Search Tree)的性质,AVL首先要满足: 若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不为空, ...

随机推荐

  1. 2、Java程序设计环境

    1.JDK Java开发工具箱 在Java 9之前,有32位和64位两个版本的Java开发工具包.现在Oracle公司不在开发32位版本,要使用Oracle JDK,你需要有一个64位的操作系统. 安 ...

  2. Linux_ZABBIX实战

    typora-copy-images-to: img ZABBIX实战 zabbix安装 Zabbix详解 zabbix中文社区: http://www.zabbix.org.cn/ Zabbix中文 ...

  3. 了解JAVA基本知识以及一下常用的dos命令

    9月5日学习 常用的Dos命令 #盘符切换盘符名称: =>回车​#查看当前目录下的所有文件dir​#切换目录 cd change directorycd .. =>返回上一级目录​#清理屏 ...

  4. linux 学习之awk

    awk 笔记 awk可以截取列 如 ll | awk '{print $3}' 获取第三列内容 参数 -F 指定分隔符 如 ls | wak -F "." '{print $1}' ...

  5. openstack:OpenStack架构详解,

    OpenStack既是一个社区,也是一个项目和一个开源软件,提供开放源码软件,建立公共和私有云,它提供了一个部署云的操作平台或工具集,其宗旨在于:帮助组织运行为虚拟计算或存储服务的云,为公有云.私有云 ...

  6. JMeter参数化(二)--数据库参数化

    1.下载mysql驱动,解压得到mysql-connector-java-8.0.17.jar(驱动一般放在java的 \java\jre\lib\ext 路径下): 2.在 测试计划-->浏览 ...

  7. Python笔记(5)——if 语句一:条件测试(Python编程:从入门到实践)

    每条if语句的核心都是一个值为True或False的表达式.Python根据条件测试的值为True还是False来决定是否执行if语句中的代码.如果条件测试的值为True,Python就执行紧跟在if ...

  8. heimaJava18_线程

    Java 线程 单线程 线程(thread)是一个程序内部的一条执行路径. main方法的执行其实就是一个单独的执行路径 程序中如果只有一条执行路径,那么这个程序就是单线程的程序 多线程 多线程是指从 ...

  9. Pintia 7-3 列车调度

    7-3 列车调度 (25 分) 火车站的列车调度铁轨的结构如下图所示. 两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道.每趟列车从入口可以选择任意一条轨 ...

  10. 针对FILES和PATH的操作

    在修改漏洞的时候发现,根据建议都使用NIO包的FILES和PATH来进行文件操作,来保证安全性. import java.nio.file.Files;import java.nio.file.Pat ...