平衡二叉树(AVL树)
二叉排序树问题分析
-
左子树全部为空,从形式上看更像一个单链表
-
插入速度没有影响
-
查询速度明显降低
-
解决方案:平衡二叉树
基本介绍
-
平衡二叉树也叫二叉搜索树,保证查询效率较高
-
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两棵子树都是一棵平衡二叉树
-
常用的实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等
平衡二叉树左旋转
使用条件
右子树高度与左子树高度插值大于1的时候,使用左旋转
要求
给定数列{4,3,6,5,7,8},创建对应的平衡二叉树
创建二叉排序树
此时若转换为平衡二叉树,降低右子树的高度
思路分析
-
创建一个新节点newNode ,值等于当前根节点的值
-
把新节点的左子树设置为当前节点的左子树,newnode.left = left
-
把新结点的右子树设置为当前节点右子树的左子树newNode.right = right.left
-
把当前节点的值换位右子节点的值 value = right.value
-
把当前节点的右子树设置成右子树的右子树right = right.right
-
把当前节点的左子树设置为新节点 left = newLeft
转换后
平衡二叉树右旋转
要求
使用数列{10,12,8,9,7,6},创建平衡二叉树
创建二叉排序树
基本思路
-
创建新的节点newNode,使得newNode.value = this.value
-
将newNode的右子树设置为this的右子树,newNode.right = this.right
-
将newNode的左子树设置为this左子树的右子树,newNode.left = this.left.right
-
把this节点的值换为左子节点的值,this.value = this.left.value
-
将this节点的左子树设置为左子树的左子树,this.left = this.left.left
-
将this节点的右子树 设置为newNode,this.right = newNode
转换后
平衡二叉树双旋转
要求
使用数列{10,11,7,6,8,9},创建平衡二叉树
创建二叉排序树
思路分析
-
当孩子节点满足左旋转或右旋转条件时,先平衡孩子 节点,后平衡父节点
创建平衡二叉树代码实现
package com.why.tree;
/**
* @Description TODO 平衡二叉树
* @Author why
* @Date 2020/12/6 15:56
* Version 1.0
**/
public class AVLTreeDemo {
public static void main(String[] args) {
int[] arr = {10,11,7,6,8,9};
//创建AVLTree对象
AVLTree avlTree = new AVLTree();
//添加节点
for (int i = 0; i < arr.length; i++) {
avlTree.add(new AVLNode(arr[i]));
}
//遍历
System.out.println("中序遍历:");
avlTree.midOrder();
//根节点树的高度
System.out.println("根节点树的高度: " + avlTree.height());
System.out.println("左子树高度:" + avlTree.leftHeight());
System.out.println("右子树高度:" + avlTree.rightHeight());
System.out.println("根节点:" + avlTree.getRoot());
}
}
/**
* AVL,平衡二叉树
*/
class AVLTree{
private AVLNode root;
public AVLNode getRoot() {
return root;
}
public void setRoot(AVLNode root) {
this.root = root;
}
/**
* 添加节点
* @param node
*/
public void add(AVLNode node){
if (root == null){//直接放上
root = node;
}else {
root.add(node);
}
}
/**
* 中序遍历
*/
public void midOrder(){
if (root != null){
root.midOrder();
}else {
System.out.println("二叉排序树为空");
}
}
/**
* 查找需删除的节点
* @param value
* @return
*/
public AVLNode search(int value){
if (root