上一篇实现了二叉搜索树,本章对二叉搜索树进行改造使之成为平衡二叉搜索树(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. sql server 连接 EXCEL 直接查询

    1  SQL SERVER 中 查看有无访问接口,以下其中任何一个即可. 没有则下载  Microsoft Access Database Engine 2016 Redistributable (M ...

  2. 记安装MySQL数据库

    记录一次自己动手安装MySQL数据库所踩的坑   MySQL安装包与操作系统匹配 安装包有amd和Intel,32位.64位多种组合需要确认仔细使用者操作系统和CPU型号 例如我使用的是CentOS ...

  3. [Cisco] IOS NAT Load-Balancing for Two ISP Connections

    interface FastEthernet0 ip address dhcp ip nat outside ip virtual-reassembly ! interface FastEtherne ...

  4. 通过网页或者移动设备链接跳转qq(tim)添加好友(群)

    首先需要去qq群官方,然后点记加群组件,然后选择群,复制对应的代码即可 登录到QQ群官网 点击加群组件 选择群,选择网页还是移动设备 复制代码 示例: <html> <head> ...

  5. CH573 CH579 CH582程序烧录讲解

    WCH的蓝牙芯片CH57x/CH58x系类大部分是支持串口烧录.USB烧录和LINK烧录的,除了一些特殊的封装,如571K,它引脚较少,只支持串口免按键烧录. 仿真下载:ARM内核的CH579支持Jl ...

  6. JSON反序列化接口的问题

    今天在使用JSON序列化类时出现问题,原来类中有一个接口,在反序列化时不知道接口的实体是什么 public class Device : IComparer {         private str ...

  7. ZooKeeper启动报错,未成功开启服务

    1.问题示例 (1)启动ZooKeeper服务报错 [Hadoop@master ~]$ zkServer.sh statusZooKeeper JMX enabled by defaultUsing ...

  8. LaTeX in 24 Hours - 1. Introduction

    文章目录 1.1 What is LaTeX? 1.2 Why LaTeX Over Other Word Processors 1.3 How to Prepare a LaTeX Input Fi ...

  9. classpath、path、JAVA_HOME的作用及JAVA环境变量配置 (转)

    CLASSPATH是什么?它的作用是什么? 它是javac编译器的一个环境变量.它的作用与import.package关键字有关.当你写下improt java.util.*时,编译器面对import ...

  10. JAVA加载PMML算法模型

    注:加载失败时尝试修改pmml文件版本为4.3 依赖 <dependency> <groupId>org.jpmml</groupId> <artifactI ...