AVL树 01 AVL树基础

AVL 树(平衡二叉树)

  • AVL树是这样定义的一棵平衡二叉树:对任意节点,左子树和右子树的高度差不能超过1;
  • AVL树中的每个节点标注了节点的高度;
  • AVL树中的每个节点都有一个平衡因子,平衡因子指的是左右子树的高度差;

AVLTree 基础代码

  • AVLTree的代码是基于之前BSTMap的代码改造的,每个节点中key和value,节点的可比较性体现在key上;
  • 相较于BSTMap,AVLTree中的节点拥有表示节点高度的属性height,叶子节点的高度为1;
import java.util.ArrayList;

public class AVLTree, 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;
        }
    }

    private Node root;
    private int size;

    public AVLTree(){
        root = null;
        size = 0;
    }

    public int getSize(){
        return size;
    }

    public boolean isEmpty(){
        return size == 0;
    }   

}

辅助方法 - 获取节点的高度值

  • 节点null的高度为0,对获取节点高度的逻辑进行简单的封装,方便在更复杂逻辑中的使用 ;
// 获得节点node的高度
private int getHeight(Node node){
    if(node == null)
        return 0;
    return node.height;
}

辅助方法 - 获取节点的平衡因子

  • 如果节点是null,它的平衡因子是0;
  • 如果节点不是null,平衡因子的计算方式为:左孩子的高 - 右孩子的高;
private int getBalanceFactor(Node node){
    if(node == null)
        return 0;
    return getHeight(node.left) - getHeight(node.right);
}

add方法相关的逻辑改动

  • 递归到底的情况并不需要修改,因为 node == null 的时候,新创建的节点只能作为整个二分搜索树的叶子节点,这是由二分搜索树的性质决定的,在AVLTree中,叶子节点的高度就是1;
  • 递归到底的结果,在原本的二分搜索树中,只需一层层的向上返回,一层层的链接回整个二分搜索树,现在在引入节点的高度值后,将递归的结果一层层的向上返回已经不够了,因为新节点的加入,可能会影响新加入节点往上追溯的整个链表中节点高度值的变化,所以递归到底的结果在返回上层之后,除了要把根节点重新链入整棵二分搜索树中之外,还要更新这条链表中上层节点的高度值;具体更新的策略是:左右孩子中,高度更大的高度值加1;
  • 在更新完节点(这条链表中除新添加的节点)的高度值后,还要计算一下节点的平衡因子,平衡因子的计算方式为:左孩子的高 - 右孩子的高;
  • 将递归到底的结果链入整个二分搜索树,结算节点的高度值,计算节点的平衡因子,这3件事是递归到底的结果在一层层向上返回的过程中,每一层都需要做的操作;
// 向二分搜索树中添加新的元素(key, value)
public void add(K key, V value){
    root = add(root, key, value);
}

// 向以node为根的二分搜索树中插入元素(key, value),递归算法
// 返回插入新节点后二分搜索树的根
private Node add(Node node, K key, V value){

    if(node == null){
        size ++;
        return new Node(key, value);
    }

    if(key.compareTo(node.key) < 0)
        node.left = add(node.left, key, value);
    else if(key.compareTo(node.key) > 0)
        node.right = add(node.right, key, value);
    else // key.compareTo(node.key) == 0
        node.value = value;

    // 更新height
    node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));

    // 计算平衡因子
    int balanceFactor = getBalanceFactor(node);
    if(Math.abs(balanceFactor) > 1)
        System.out.println("unbalanced : " + balanceFactor);

    return node;
}

你可能感兴趣的