java平衡二叉树AVL数

Posted lee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java平衡二叉树AVL数相关的知识,希望对你有一定的参考价值。

     平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

     右旋:在插入二叉树的时候,根节点的右侧高度大于左侧高度,且绝对值超过了2,并且在root.左侧的值大于插入的值时发生右旋 。

  左右旋:在插入二叉树的时候,根节点的右侧高度大于左侧高度,且绝对值超过了2,并且在root.左侧的值小于插入的值时发生,先对root的左子树发生左旋,再对root右旋。

     左旋:在插入二叉树的时候,根节点的左侧高度大于右侧,绝对值超过2,且root右侧的值小于插入的值,这个时候发生左旋。

  右左旋:在插入二叉树的时候,根节点的左侧高度大于右侧,绝对值超过2,且root右侧的值大于插入的值,这个时候发生右左旋。先对root的右子树发生右旋,再对root树发生左旋。

   

 

package com.lee.test;

/**
 *  平衡二叉树 插入、删除、遍历
 */
public class AVLTree {
    private class Node{
        private Node left;
        private Node right;
        private int value;
        private int height = -1;
        private Node (int value){
            this.value = value;
        }
        private Node(){

        }
    }
    private Node head;  //头
    public AVLTree(){
    }

    /**
     * 获取高度
     * @param root
     * @return
     */
    private int Height(Node root){
        if (root == null){
            return -1;
        }else {
            return root.height;
        }
    }

    /**
     * 右旋
     * @return
     */
    private Node rotateRight(Node root){
        Node temp = root.left;
        root.left = temp.right;
        temp.right = root;
        root.height = Math.max(Height(root.left),Height(root.right)) +1; //高度设置为两者中最高的一个
        temp.height = Math.max(Height(temp.left),Height(temp.right)) +1; //高度设置为两者中最高的一个
        return temp;
    }
    /**
     * 左旋
     * @return
     */
    private Node rotateLeft(Node root){
        Node temp = root.right;
        root.right = temp.left;
        temp.left = root;
        root.height = Math.max(Height(root.left),Height(root.right)) +1; //高度设置为两者中最高的一个
        temp.height = Math.max(Height(temp.left),Height(temp.right)) +1; //高度设置为两者中最高的一个
        return temp;
    }

    /**
     * 左右旋转
     * @param node
     * @return
     */
    private Node rotateLeftRight(Node node){
        node.left = rotateLeft(node.left);
        return rotateRight(node);
    }

    /**
     * 右左旋转
     * @param node
     * @return
     */
    private Node rotateRightLeft(Node node){
        node.right = rotateRight(node.right);
        return rotateLeft(node);
    }
    //插入
    public Node insert(Node root ,int value){
        if (root == null){
            root = new Node(value);
        }else if(value <root.value){ //插入左边
            root.left = insert(root.left,value);
            if (Height(root.left) - Height(root.right) == 2){ //需要左旋
                if (value < root.left.value){
                    root = rotateRight(root);
                }else{
                    root = rotateLeftRight(root);
                }
            }
        }else{
            root.right = insert(root.right,value);
            if (Height(root.right) - Height(root.left) ==2) //需要右旋
            {
                if (value > root.right.value){
                    root = rotateLeft(root);
                }else {
                    root = rotateRightLeft(root);
                }
            }
        }
        root.height = Math.max(Height(root.left),Height(root.right))+1;
        return root;
    }

    private Node deleteNode(Node root,int value) {
        if(root == null) return root;//根节点null 无操作
        if(value < root.value) {
            root.left = deleteNode(root.left, value); //删除可能发生在左边,继续向下遍历左子树
        }else if(value > root.value) {
            root.right = deleteNode(root.right, value); //删除可能发生在右边,继续向下遍历右子树
        }else {   //找到需要删除的节点
            if(root.left!=null && root.right!=null) {
                //如果当前结点左右子树不为空,将问题转化为 删除一个子节点为空的节点
                Node pre = root.right;
                while(pre.left != null) {
                    pre = pre.left;
                }
                root.value = pre.value;
                root.right = deleteNode(root.right, pre.value);
            }else { //左右结点仅有一个或者都为空,删除该节点,如果有子节点 用子节点直接覆盖
                root = (root.left != null) ? root.left : root.right;
            }
        }
        //删除完成,调整平衡性
        if(root == null) return root;
        root.height = Math.max(Height(root.left), Height(root.right))+1;
        //失衡
        if(Height(root.left)-Height(root.right)>=2) {
            //删除发生在右子树,模拟插入发生在左子树
            if(Height(root.left.left) > Height(root.left.right)) {
                //插入发生在左子树,LL旋转
                return rotateLeft(root);
            }else {
                //LR旋转
                return rotateLeftRight(root);
            }
        }else if(Height(root.left)-Height(root.right)<=-2){
            //删除发生在左子树,模拟插入发生在右子树
            if(Height(root.right.left) > Height(root.right.right)) {
                //RL旋转
                return rotateRight(root);
            }else {
                //RR旋转
                return rotateRightLeft(root);
            }
        }
        //未失衡,不做操作
        return root;
    }

    //遍历
    private void print(Node node){
        if (node == null){
            return;
        }

        print(node.left);
        System.out.print(node.value+" ");
        print(node.right);
   //     System.out.println();
    }

    public void add(int value){
        head = insert(head,value);
    }
    public void delete(int value){
        head = deleteNode(head,value);
    }

    public void show(){
        print(head);
        System.out.println();
    }
    public static void main(String args[]){
        AVLTree tree = new AVLTree();
        tree.add(24);
        tree.add(20);
        tree.add(26);
        tree.add(18);
        tree.add(22);
        tree.add(23);
        tree.add(19);
        tree.add(21);
        tree.add(17);
        tree.add(10);
        tree.add(12);
        tree.add(14 );
        tree.show();
        tree.delete(22);
        tree.show();
    }
}

  

以上是关于java平衡二叉树AVL数的主要内容,如果未能解决你的问题,请参考以下文章

平衡二叉树(AVL数)

数据结构手写平衡二叉树(AVL)

深入理解平衡二叉树(AVL)

平衡二叉树 AVL树结构详解 [Java实现]

树--07---二叉树--04--平衡二叉树(AVL树)

平衡二叉树 AVL树结构详解 [Java实现]--源码部分