上一篇实现了二叉搜索树,本章对二叉搜索树进行改造使之成为平衡二叉搜索树(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. IE浏览器下bootStrap form-control input输入框不显示兼容性问题

    问题背景 采用了如下代码. 主要时bootstrap 搜索框. 再IE11下表现出 input 明明 value有值,但是显示不出来的问题. 排查发现form-control样式去后功能正常,但是样式 ...

  2. 手机设置fiddler代理后无法上网

    方法一:打开防火墙设置 参考链接:https://www.jianshu.com/p/b122eab059c4 1.打开控制面板->系统和安全->Windows Defender 防火墙, ...

  3. 一些狗J8稳定性测试

    1.CTS 2.NTS 3.高温老化 4.DDR 稳定度 5.一些HW 指标

  4. Blog作业03

    目录 前言 设计与分析 踩坑心得 改进建议 总结 前言 这三次作业的题目只有2道题,但是在题量减小的同时,这三次作业集的难度也相应的上去了,题目的质量很好,运用很广泛,也考验了很多的知识点.这三次的作 ...

  5. bbswitch与bumblebee配合使用

    !建议查阅并使用archwiki的bumblebee方案 ! 安装NONFREE驱动 1.在终端中输入以下命令来检查已安装的驱动版本(我这次装manjaro是hybird440) inxi -G 2. ...

  6. 切片slice

    1.切片 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用类型的机制 切片的使用和数组类似,如遍历切片,访问切片的元素和求切片长度len(slice)都一样. 切片的长度是可以变化的, ...

  7. Use `tensor.item()` in Python or `tensor.item<T>()` in C++ to convert a 0-dim tensor to a number

    IndexError: invalid index of a 0-dim tensor. Use `tensor.item()` in Python or `tensor.item<T>( ...

  8. git 更换远程连接

    原来的git仓库不可用,更换远程仓库 查看远程仓库地址 git remote -v 删除远程仓库 git remote rm origin 添加远程仓库地址 git remote add origin ...

  9. 学习记录--C++多态性简答+编程题

    #include<iostream> #include<string> //双目运算符:运算符作用域两个操作数 //定义一个复数类,重载"+",作为复数类的 ...

  10. conda使用杂记

    总纲 https://docs.anaconda.com/anaconda/navigator/ 其中有链接 miniconda https://docs.anaconda.com/anaconda/ ...