上一篇实现了二叉搜索树,本章对二叉搜索树进行改造使之成为平衡二叉搜索树(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树)的更多相关文章

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

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

  2. 看动画学算法之:平衡二叉搜索树AVL Tree

    目录 简介 AVL的特性 AVL的构建 AVL的搜索 AVL的插入 AVL的删除 简介 平衡二叉搜索树是一种特殊的二叉搜索树.为什么会有平衡二叉搜索树呢? 考虑一下二叉搜索树的特殊情况,如果一个二叉搜 ...

  3. 高度平衡的二叉搜索树(AVL树)

    AVL树的基本概念 AVL树是一种高度平衡的(height balanced)二叉搜索树:对每一个结点x,x的左子树与右子树的高度差(平衡因子)至多为1. 有人也许要问:为什么要有AVL树呢?它有什么 ...

  4. 平衡二叉搜索树AVL

    package com.sunshine.AlgorithmTemplate; import com.sunshine.OFFER66_SECOND.BalanceTreeNode; import c ...

  5. 平衡二叉搜索树/AVL二叉树 C实现

    //AVTree.h #ifndef MY_AVLTREE_H #define MY_AVLTREE_H typedef int ElementType; struct TreeNode { Elem ...

  6. 二叉搜索树、AVL平衡二叉搜索树、红黑树、多路查找树

    1.二叉搜索树 1.1定义 是一棵二叉树,每个节点一定大于等于其左子树中每一个节点,小于等于其右子树每一个节点 1.2插入节点 从根节点开始向下找到合适的位置插入成为叶子结点即可:在向下遍历时,如果要 ...

  7. 手写AVL平衡二叉搜索树

    手写AVL平衡二叉搜索树 二叉搜索树的局限性 先说一下什么是二叉搜索树,二叉树每个节点只有两个节点,二叉搜索树的每个左子节点的值小于其父节点的值,每个右子节点的值大于其左子节点的值.如下图: 二叉搜索 ...

  8. 算法:非平衡二叉搜索树(UnBalanced Binary Search Tree)

    背景 很多场景下都需要将元素存储到已排序的集合中.用数组来存储,搜索效率非常高: O(log n),但是插入效率比较低:O(n).用链表来存储,插入效率和搜索效率都比较低:O(n).如何能提供插入和搜 ...

  9. LeetCode 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树

    第108题 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10 ...

  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 ...

随机推荐

  1. Matlab字体设置中找不到字体的解决方法(转载)

    Matlab字体设置中找不到字体 Matlab默认的字体实在不好看,一般都需要重新设置字体. 在其字体设置中有些字体不能同时支持中文和英文,我在之前的博客中说过,如何为Matlab设置一款好看的同时兼 ...

  2. revit转tileset 3dmax转tileset cesium展示

    使用revit软件导出fbx模型: 使用glTFExport导出gltf模型,导出的gltf模型具有属性.但是此处导出gltf模型,不是为了在cesium中加载该gltf模型,主要目的是获取组件属性信 ...

  3. NX二次开发获取当前DLL路径函数

    string GetPath();//输出程序路径 string YiNingToolPath(string DLLDir); //分割程序路径获取工具目录 HMODULE GetSelfModule ...

  4. [Lua]敏感字检测

    参考链接: https://zhuanlan.zhihu.com/p/84685657 https://www.cnblogs.com/luguoshuai/p/9254190.html 一开始打算使 ...

  5. 实验十 团队作业7:团队项目用户验收&Beta冲刺

    项目 内容 课程班级博客链接 2018级卓越班 这个作业要求链接 实验十 团队名称 零基础619 团队成员分工描述 任务1:亚楠,桂婷任务2:团队合作任务3:团队合作任务4:荣娟,鑫 团队的课程学习目 ...

  6. Neo4j学习(2)--简单入门

    1.Neo4j属性图数据模型 节点:包含多个属性和标签.一个节点就是一条数据 属性:键值对形式 关系:单向与双向,连接节点,也可包含多个属性和标签 标签:表示节点和关系的类型,可以有多个,同时可以通过 ...

  7. 如何高效实现 MySQL 与 elasticsearch 的数据同步

    MySQL 自身简单.高效.可靠,是又拍云内部使用最广泛的数据库.但是当数据量达到一定程度的时候,对整个 MySQL 的操作会变得非常迟缓.而公司内部 robin/logs 表的数据量已经达到 800 ...

  8. 火山引擎 DataLeap:一家企业,数据体系要怎么搭建?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 导读:经过十多年的发展,数据治理在传统行业以及新兴互联网公司都已经产生落地实践.字节跳动也在探索一种分布式的数据治 ...

  9. 你可能需要的 6 个 React 开发小技巧

    ​ 这是一个可怕的问题,在React中,我们经常会编写条件语句来显示不同的视图,比如这个简单的例子. const App = () => { return ( <> { loadin ...

  10. Gitee 码云与Git 交互

    一.进入码云官方网站,注册用户 官网地址:https://gitee.com/ 二.创建远程仓库 [1]点击右上角的 + 号进行创建