1、平衡二叉树和AVL树
2、旋转操作的基本原理
下面介绍的是AVL树实现自平衡的机制!
3、LR与RL的不平衡情况
4、AVL树的删除
AVL树中添加元素可能导致整棵树变得不平衡,删除某个元素也是一样的,可能使得整棵树变得不平衡!
AVL树相应的代码如下:
package com.lkj;
import java.util.ArrayList;
/**
AVL平衡二叉树其实就是在之前的二分搜索树的基础上实现的,其实就是在二分搜索树的基础上添加上自平衡的机制,
使得二分搜索树在堆结点进行操作的时候,可以保证整棵树是平衡的(即每一个结点左右子树的高度差不超过1),不会退化。
*/
public class AVLTree<K extends Comparable<K>, V> {
private class Node{
public K key;
public V value;
public Node left, right;
public int height;//记录每一个结点的高度值
public Node(K key, V value){
this.key = key;
this.value = value;
left = null;
right = null;
height = 1;//结点都是添加到叶子结点处,因此每一个结点初始化的时候,高度值都是1
}
}
private Node root;
private int size;
public AVLTree(){
root = null;
size = 0;
}
//---------------------------------------------------------------------------------新增的辅助方法
//辅助函数,返回每一个结点的高度值(主要是为了处理结点为null的情况,后面就不需要判断结点为null的情况)
private int getHeight(Node node)
{
if(node == null)
return 0;//空结点的高度为0
return node.height;
}
//辅助函数:计算结点的平衡因子
private int getBalanceFactor(Node node)
{
if(node == null)
return 0;
return getHeight(node.left) - getHeight(node.right);//左子树的高度减去右子树的高度
}
/** AVL 树既要满足平衡二叉树的特性(所有结点左右子树高度差小于1),又要满足二分搜索树的特性
* (AVL树是改进二分搜索树,引入平衡因子,使得二分搜索树不会退化为链表) */
// 判断该二叉树是否是一棵二分搜索树(利用二分搜索树中序遍历是升序的机制)
private boolean isBST()
{
ArrayList<K> keys = new ArrayList<>();//用于存储所有结点的key
inOrder(root , keys);//利用中序遍历,将以root为根的树的所有结点添加到keys中
for (int i = 1; i < keys.size(); i++)
{
if(keys.get(i-1).compareTo(keys.get(i)) > 0)//如果中序遍历后keys的key中不是升序,则该树不是二分搜索树
return false;
}
return true;
}
//中序遍历的方法
private void inOrder(Node node , ArrayList<K> keys