1. AVL平衡树的介绍:AVL平衡树是由G.M.Adelson-Velsky和E.M.Landis两人创建,因此命名为AVL。AVL平衡树是一种最早的自平衡二分搜索树结构,满二叉树一定是平衡二叉树,高度最低;完全二叉树也是平衡二叉树。
2. AVL平衡树的定义:对于AVL平衡树而言,其任意一个节点,左子树和右子树的高度差都不能超过1。
3. AVL平衡树的平衡因子:节点的左右子树的高度差。
4. AVL平衡树的调整:当向树中添加或删除节点时,会对树的结构发生改变,因此就需要进行平衡调整。
5. 平衡调整的方式:
1>. 左旋转:即当插入的元素在不平衡结点的右侧的右侧时,可以用左旋转进行平衡调整。
2>. 右旋转:即当插入的元素在不平衡结点的左侧的左侧时,可以用右旋转进行平衡调整。
3>. 左右旋转:即当插入的元素在不平衡结点的左侧的右侧时,可以先用左旋转,再用右旋转进行平衡调整。
4>. 右左旋转:即当插入的元素在不平衡结点的右侧的左侧时,可以先用右旋转,再用左旋转进行平衡调整。
6. 映射接口的定义:
public interface Map<K, V> {
//向map中添加键值对
public void put(K key, V value);
//删除map中指定key的键值对
public V remove(K key);
//判断二分搜索树中是否包含指定key
public boolean contains(K key);
//通过key从map中获取key对应的值
public V get(K key);
//修改指定key对应的值
public void set(K key, V value);
//获取map中有效元素的个数
public int size();
//判断map是否为空
public boolean isEmpty();
//获取map中的键的集合 因为map中键key是唯一的 所以用集合set进行存储
public Set<K> keySet();
//获取map中的值的列表 因为map中键value不是唯一的 所以用列表list进行存储
public List<V> values();
//获取map中键值对的集合 因为map中键值对(key:value)是唯一的 所以用集合set进行存储
public Set<Entry<K, V>> entrySet();
//定义一个获取键值对Entry<K, V>的接口
public interface Entry<K, V> extends Comparable<Entry<K, V>>{
//获取键值对的键
public K getKey();
//获取键值对的值
public V getValue();
}
}
7. 底层通过AVL平衡树实现的映射数据结构的实现:
//底层通过AVL平衡树实现的映射
/*
* AVL平衡树是最早的一种二分搜索树之一 因此AVL平衡树实现的映射中的key也应具有比较性
* 只有一个树的每个节点的平衡因子的绝对值 小于等于1 该树才能称为平衡树
* 平衡因子:当前节点的左子树高度减右子树高度的差值小于1 或者 大于-1
* 节点高度:节点的左右子树中高度的最大值 加1
*
* 每次进行添加和删除节点后 都应更新节点的高度 并且进行平衡调整
* 在AVL平衡树中平衡调整有四种方法 右旋转 左旋转 左右旋转 右左旋转
* 右旋转:适用于不平衡节点位于当前节点左侧的左侧
* 左旋转:适用于不平衡节点位于当前节点右侧的右侧
* 左右旋转:适用于不平衡节点位于当前节点左侧的右侧
* 右左旋转:适用于不平衡节点位于当前节点右侧的左侧
*/
public class AVLTreeMap<K extends Comparable<K>, V> implements Map<K, V>{
//创建AVL平衡树的节点 由五部分构成
//键key 值value 节点高度height 左孩子指针 右孩子指针
private class Node{
private K key; //表示节点的键
private V value; //表示节点的值
private int height; //表示结点的高度 默认高度为1
private Node leftChild; //指针域 指向节点的左孩子
private Node rightChild; //指针域 指向节点的右孩子
public Node(K key, V value) {
this.key = key;
this.