Java实现平衡二叉搜索树(AVL树)
上一篇实现了二叉搜索树,本章对二叉搜索树进行改造使之成为平衡二叉搜索树(Balanced Binary Search Tree)。
不平衡的二叉搜索树在极端情况下很容易退变成链表,与新增/删除/查找时间复杂度为O(logN)的目标又远了一步。
平衡二叉搜索树始终围绕O(logN)这个目标来构建数据结构。
节点类和实现类:
/**
* 二叉搜索树节点&平衡二叉搜索树添加节点时自平衡实现
*/
public class Node
{
private int data;//数据域
private Node left;//左节点(左孩子)
private Node right;//右节点(右孩子) public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
} //构造函数
public Node(int data, Node left, Node right){
this.data = data;
this.left = left;
this.right = right;
}
public Node(int data){
this(data,null,null);
}
public Node(){
this(0,null,null);
} //求该结点的高度
public int getHeight(){
return Math.max(this.left==null?0:this.left.getHeight(),this.right==null?0:this.right.getHeight())+1;
} //左节点的高度
public int getLeftHeight(){
if(this.left==null)
return 0;
else
return this.left.getHeight();
}
//右节点的高度
public int getRightHeight(){
if(this.right==null)
return 0;
else
return this.right.getHeight();
} //左旋
public void leftRotate(){
Node node=new Node(this.data);
node.left=this.left;
node.right=this.right.left;
this.data=this.right.data;
this.right=this.right.right;
this.left=node;
} //右旋
public void rightRotate(){
Node node=new Node(this.data);
node.right=this.right;
node.left=this.left.right;
this.data=this.left.data;
this.left=this.left.left;
this.right=node;
} /**
* 向二叉排序树添加结点
* @param node
*/
public void add(Node node){
if(node==null){
return;
}
if(node.data<this.data){
if(this.left==null){
this.setLeft(node);
}
else{
this.left.add(node);
}
}
else{
if(this.right==null){
this.setRight(node);
}
else{
this.right.add(node);
}
} //右子树的高度-左子树的高度)>1,左旋转
if(this.getRightHeight()-this.getLeftHeight()>1){
//如果它的右子树的左子树高度大于它的左子树高度,双旋转
if(this.right!=null&&this.right.getLeftHeight()>this.getLeftHeight()){
//先对这个结点的右节点进行右旋转
this.right.rightRotate();
}
//左旋转
this.leftRotate();
}
//左子树的高度-右子树的高度)>1,右旋转
else if(this.getLeftHeight()-this.getRightHeight()>1){
//如果它的左子树的右子树高度大于它的右子树高度,双旋转
if(this.left!=null&&this.left.getRightHeight()>this.getRightHeight()){
//先对这个结点的左节点进行左旋转
this.left.leftRotate();
}
//右旋转
this.rightRotate();
}
else{
return;
}
} }
测试类:
import java.util.*;
public class Main {
public static void main(String[] args) {
/**
* 平衡二叉搜索树测试
*/
Node root = new Node(25);
root.add(new Node(18));
root.add(new Node(16));
root.add(new Node(19));
root.add(new Node(29));
root.add(new Node(27));
root.add(new Node(30));
root.add(new Node(31));
root.add(new Node(32)); //输出树
System.out.println(Arrays.toString(levelOrder(root)));
root.add(new Node(35));
root.add(new Node(36));
System.out.println(Arrays.toString(levelOrder(root)));
} /**
* 层序遍历
* @param root
* @return
*/
public static int[] levelOrder(Node root) {
if(root == null){
return new int[0];
} Queue<Node> queue = new LinkedList<Node>();
queue.add(root);
ArrayList<Integer> arr = new ArrayList<>();
while( !queue.isEmpty() ){
Node temp = queue.poll();
arr.add(temp.getData());
if(temp.getLeft() != null){
queue.add(temp.getLeft());
}
if(temp.getRight() != null){
queue.add(temp.getRight());
}
}
int[] res = new int[arr.size()];
for(int i = 0;i < arr.size();i++){
res[i] = arr.get(i);
} return res; } }
执行结果:

*重点:
1,平衡二叉搜索树是一种高度平衡的二叉树;
2,由于对平衡的高要求,插入删除时会对树进行频繁的旋转操作。
Java实现平衡二叉搜索树(AVL树)的更多相关文章
- 树-二叉搜索树-AVL树
树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...
- 看动画学算法之:平衡二叉搜索树AVL Tree
目录 简介 AVL的特性 AVL的构建 AVL的搜索 AVL的插入 AVL的删除 简介 平衡二叉搜索树是一种特殊的二叉搜索树.为什么会有平衡二叉搜索树呢? 考虑一下二叉搜索树的特殊情况,如果一个二叉搜 ...
- 高度平衡的二叉搜索树(AVL树)
AVL树的基本概念 AVL树是一种高度平衡的(height balanced)二叉搜索树:对每一个结点x,x的左子树与右子树的高度差(平衡因子)至多为1. 有人也许要问:为什么要有AVL树呢?它有什么 ...
- 平衡二叉搜索树AVL
package com.sunshine.AlgorithmTemplate; import com.sunshine.OFFER66_SECOND.BalanceTreeNode; import c ...
- 平衡二叉搜索树/AVL二叉树 C实现
//AVTree.h #ifndef MY_AVLTREE_H #define MY_AVLTREE_H typedef int ElementType; struct TreeNode { Elem ...
- 二叉搜索树、AVL平衡二叉搜索树、红黑树、多路查找树
1.二叉搜索树 1.1定义 是一棵二叉树,每个节点一定大于等于其左子树中每一个节点,小于等于其右子树每一个节点 1.2插入节点 从根节点开始向下找到合适的位置插入成为叶子结点即可:在向下遍历时,如果要 ...
- 手写AVL平衡二叉搜索树
手写AVL平衡二叉搜索树 二叉搜索树的局限性 先说一下什么是二叉搜索树,二叉树每个节点只有两个节点,二叉搜索树的每个左子节点的值小于其父节点的值,每个右子节点的值大于其左子节点的值.如下图: 二叉搜索 ...
- 算法:非平衡二叉搜索树(UnBalanced Binary Search Tree)
背景 很多场景下都需要将元素存储到已排序的集合中.用数组来存储,搜索效率非常高: O(log n),但是插入效率比较低:O(n).用链表来存储,插入效率和搜索效率都比较低:O(n).如何能提供插入和搜 ...
- LeetCode 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树
第108题 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10 ...
- convert sorted list to binary search tree(将有序链表转成平衡二叉搜索树)
Given a singly linked list where elements are sorted in ascending order, convert it to a height bala ...
随机推荐
- 11、jmeter配置元件--计数器
前面学过csv和变量 csv里面的数据是固定的 如果里面的数据不够 线程要么就停止要么就需要重头再来 不太灵活 用到固定化的数据,比如说多少个用户等等 如果有一些是变动的 随着线程数增加 数据 ...
- mac安装mysql5.6默认密码修改
前言: 每次安装mysql都被烦的要死,痛并思痛记下此篇文章: 参考: https://blog.csdn.net/u010377383/article/details/82688250 https: ...
- selenium--- 数据驱动测试 ddt
通过使用数据驱动测试的方法,可以在需要验证多组数据的测试场景中,使用外部数据源实现对输入值和期望值的参数化,从而避免在测试中仅使用硬编码的数据.将测试数据和测试脚本分离开,使得测试脚本在不同数据集合下 ...
- 转帖:巧用Stream优化老代码,太清爽了!
Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读 放大招,流如何简化代码 如果有一个需求,需要对数据库 ...
- word多级标题自动编号设置
1.选择段落 ->多级列表 ->定义新的多级列表 2.级别设置 ,这里操作比较繁琐,要多注意[输入编号的格式]要通过[包含的级别编号来自]这一项目来设定 标题1: 标题2 标题3: 标题4 ...
- JDMasking v0.1.0-beta 发布
JDMasking 全称是jdbc data masking,是一款零代码修改.无重启.基于JDBC的动态数据脱敏软件. JDMasking 主要对实现jdbc的驱动进行字节码的增强,支持对运行中的程 ...
- Python使用Eel和HTML开发桌面应用GUI直接用web前端的VUE+VANT来做
python的gui太难用了,唯一能配置独立前端的程序只有web.所以用web做前端,到python,完美! 环境准备 Python 3.9 Chrome浏览器(由于Eel是直接调用的Ch ...
- class1,2,3,4,5,6,7
//测试你是哪一类学者 #include<stdio.h> int main() { int ans; char words[5000]; printf("网课学习让一些人喜一些 ...
- Go_day01
Go基础语法 注释 注释是为了增强代码的可读性,不会参与程序的一切功能, go语言注释分为单行注释与多行注释 单行注释 //双斜杠 每行都要添加 // 多行注释 /* */ 一次标记多行注释输入 pa ...
- 记一下Linux环境SpringBoot 用OpenOffice Word转PDF
环境 Windows或者Linux 首先安装 deb方式 tar -xvzf Apache_OpenOffice_XXXX_Linux_x86-64_install-deb_zh-CN.tar.gz ...