数据结构与算法-AVL树

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhangdong2012/article/details/99958903

AVL树实际上是为了解决二分搜索树在极端情况下退化成链表的问题。AVL树通过自动调节左右子树的高度可以保证查找时间复杂度在O(logN)。

在AVL树中,新增节点的默认高度是1,新增节点的父节点默认高度是2,以此类推。左子节点的高度与右子节点的高度差成为平衡因子。在AVL树中,要求所有节点的平衡因子都小于等于1。

由于节点的平衡因子是通过左右子树的高度计算的,所以我们就需要在节点中记录当前节点的高度值。

还是直接看代码。

package loop;

import java.util.ArrayList;
import java.util.List;

//平衡树
public class AVLTree<E extends Comparable<E>> {


    private Node<E> root;
    private int size;



    // 判断是否为二叉搜索树
    public boolean isBst() {
        List<E> eList = new ArrayList<>();
        inOrder(eList, root);

        for (int i = 1;i < eList.size();i ++) {
            if (eList.get(i-1).compareTo(eList.get(i)) > 0) {
                return false;
            }
        }
        return true;
    }

    private void inOrder(List<E> eList, Node<E> node) {
        if(node == null) {
            return;
        }

        inOrder(eList, node.left);
        eList.add(node.data);
        inOrder(eList, node.right);
    }


    private int getHeight(Node<E> node) {
        if (node == null) {
            return 0;
        }
        return node.height;
    }

    private int getBalanceFactor(Node<E> node) {
        if (node == null) {
            return 0;
        }
        //左- 右
        return getHeight(node.left) - getHeight(node.right);
    }

    private boolean isBalanced(Node<E> node) {
        if (node == null) {
            return true;
        }
        int balanceFactor = getBalanceFactor(node);
        if (Math.abs(balanceFactor) > 1) {
            return false;
        }
        return isBalanced(node.left) && isBalanced(node.right);
    }

    public boolean isBalanced() {
        return isBalanced(root);
    }



    //添加节点
    public void add(E e) {
        root = add(root, e);
    }

    private Node<E> add(Node<E> node, E e) {
        if (node == null) {
            this.size ++;
            return new Node(e);
        }


        Node<E> retNode ;
        if (e.compareTo(node.data) > 0) {
            node.right = add(node.right, e);
        } else if (e.compareTo(node.data) < 0) {
            node.left = add(node.left, e);
        } else {
            node.data = e;
        }

        //更新当前节点高度

        node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));
        int balanceFactor = getBalanceFactor(node);

        //LL
        if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) {
            //右旋转
            return rightRotate(node);
        }

        if (balanceFactor < -1 && getBalanceFactor(node.right) < 0) {
            //左旋转
            return leftRotate(node);
        }

        //LR
        if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }

        //RL
        if (balanceFactor < -1 && getBalanceFactor(node.right) > 0) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }
        return node;
    }

    public void remove(E e) {

    }

    private Node<E> remove(Node<E> node, E e) {
        if (node == null) {
            return null;
        }
        Node<E> retNode ;
        if (e.compareTo(node.data) > 0) {
            node.right = remove(node.right, e);
            retNode = node;
        } else if (e.compareTo(node.data) < 0){
            node.left = remove(node.left, e);
            retNode = node;
        } else {
            //找到了待删除的节点
            if (node.left == null) {
                Node<E> right = node.right;
                node.right = null;
                this.size --;
                retNode = right;
            } else if (node.right == null) {
                Node<E> left = node.left;
                node.left = null;
                this.size --;
                retNode = left;
            } else {
                /**
                  即有左子树 又 有右子树
                 * */
                Node<E> rightMinNode = minNode(node.right);
                rightMinNode.right = remove(node.right, rightMinNode.data);
                rightMinNode.left = node.left;

                node.left = node.right = null;
                this.size --;

                retNode = rightMinNode;
            }

        }

        //调整平衡性
        if (retNode == null) {
            return null;
        }

        //更新高度
        retNode.height = Math.max(getHeight(retNode.right), getHeight(retNode.left)) + 1;
        //获取平衡因子
        int balanceFactor = getBalanceFactor(retNode);

        //LL
        if (balanceFactor > 1 && getBalanceFactor(retNode.left) >= 0) {
            //右旋转
            return rightRotate(node);
        }

        if (balanceFactor < -1 && getBalanceFactor(retNode.right) < 0) {
            //左旋转
            return leftRotate(node);
        }

        //LR
        if (balanceFactor > 1 && getBalanceFactor(retNode.left) < 0) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }

        //RL
        if (balanceFactor < -1 && getBalanceFactor(retNode.right) > 0) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }

        return retNode;
    }

    private Node<E> minNode(Node<E> node) {
        if (node == null) {
            return null;
        }
        if (node.left == null) {
            return node;
        }
        return minNode(node.left);
    }


    //左旋转
    public Node rightRotate(Node<E> node) {
        Node<E> x = node.left;
        Node<E> t1 = x.right;

        x.right = node;
        node.left = t1;

        node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
        x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;

        return x;
    }

    //右旋转
    public Node leftRotate(Node<E> node) {
        Node<E> x = node.right;
        Node<E> t1 = x.left;

        x.left = node;
        node.right = t1;

        node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
        x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;

        return x;
    }



    //删除节点


    private class Node<E> {
        E data;
        Node<E> left;
        Node<E> right;

        int height;

        public Node(E data) {
            this.data = data;
            this.left = null;
            this.right = null;
            this.height = 1;
        }
    }

}

猜你喜欢

转载自blog.csdn.net/zhangdong2012/article/details/99958903
今日推荐