上一篇实现了二叉搜索树,本章对二叉搜索树进行改造使之成为平衡二叉搜索树(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. 【confluence】jira issue宏中如何把优先级图标转义成文字

    在confluece中,关于表格处理有2个非常好的插件. Table Filter and Charts for Confluence     (插件文档:https://docs.stiltsoft ...

  2. SpringCloud之旅

    现在大部分公司的项目架构都选择了微服务,我们公司也不例外,那么什么是微服务呢?今天就来开启SpringCloud之旅! SpringCloud是基于SpringBoot的一整套的微服务架构.他提供了微 ...

  3. Linux 提示符后面显示全路径

    vi /root/.bashrc # .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' a ...

  4. What Are You Weighting For?

    A basic strength routine can change your life Strength training isn't just about getting six-pack ab ...

  5. python和java语法对比

      python java 不同的关键字 except,nolocal,as,assert,async,pass ,await,from,raise,global,in,del,with,lambda ...

  6. windows下创建虚拟环境

    创建虚拟环境依赖以下两个模块 virtualenv  和virtualenvwrapper-win 1.下载 2.修改环境变量,增加一条 WORKON_HOME:路径 3.  同步配置 去向Pytho ...

  7. c++方便的输出vector和map_重载的应用 【python一样写c++、二】

    写程序,尤其是调试的时候,会想着直接输出一个map或者vector来调错. 但本来的cout<<没有这种功能.我们就会想了,要是c++能和python一样,直接输出一个列表(vector) ...

  8. python安装第三方库出现“'pip' is not recognized ...”报错及其解决

    命令行安装第三方库,直接 通过命令 pip install XXX 会报错: 'pip' is not recognized as an internal or external command, o ...

  9. 迁移学习(CDAN)《Conditional Adversarial Domain Adaptation》(已复现迁移)

    论文信息 论文标题:Conditional Adversarial Domain Adaptation论文作者:Yaroslav Ganin, Evgeniya Ustinova, Hana Ajak ...

  10. Python相关练习说明

    Python练习情况说明 1.练习了在文件中进行统计的相关方法,基本操作其实差不多,步骤基本如下: # 1.打开相关文件,然后利用for循环进行按行读取的操作 # 2.读取的过程中,将读取到的数据加以 ...