码迷,mamicode.com
首页 > 编程语言 > 详细

AVL树的Java实现

时间:2019-01-27 14:31:00      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:tno   turn   node   key   class   接口   .com   左右子树   insert   

AVL树:平衡的二叉搜索树,其子树也是AVL树。

以下是我实现AVL树的源码(使用了泛型):

import java.util.Comparator;

public class AVLTree<T extends Comparable<T>> {
    /*
    AVL树:
    左右子树高度绝对值最多差1的二叉搜索树
    子树也是AVL树
     */
    private Node<T> root;
    class Node<T extends Comparable<T>>{
        T key;
        int height;
        Node<T> left;
        Node<T> right;

        public Node(T key, int height, Node<T> left, Node<T> right) {
            this.key = key;
            this.height = height;
            this.left = left;
            this.right = right;
        }
        public Node(T key){
            this.key = key;
            this.height = 0;
        }
    }
    public int getHeight(Node<T> node){
        return node == null ? 0 : node.height;
    }
    public Node<T> LL(Node<T> node){
        //左子树插入节点在左导致不平衡,需要旋转,以下不再赘述
        Node<T> leftNode = node.left;
        node.left = leftNode.right;
        leftNode.right = node;
        node.height = Math.max(node.left.height,node.right.height) + 1;
        leftNode.height = Math.max(leftNode.left.height, leftNode.right.height) + 1;
        return leftNode;
    }
    public Node<T> RR(Node<T> node) {
        Node<T> rightNode;
        rightNode = node.right;
        node.right = rightNode.left;
        rightNode.left = node;

        node.height = Math.max( node.left.height, node.right.height) + 1;
        rightNode.height = Math.max( rightNode.left.height, rightNode.right.height) + 1;
        return rightNode;
    }
    public Node<T> LR(Node<T> node){
        //LR先对左子树RR再对本树LL
        node.left = RR(node.left);
        return LL(node);
    }
    public Node<T> RL(Node<T> node){
        node.right = LL(node.right);
        return RR(node);
    }
    public Node<T> insert(Node<T> root,T key){
        /*
        插入:先判断插入点,再判断是否需要翻转
         */
        if(root == null){
            return new Node<T>(key);
        }
        else{
            if(key.compareTo(root.key)<0)
            //T是实现了comparable接口的,所以这里可以比较,但不能用大小于号
            {
                root.left = insert(root.left,key);
                if(root.left.height - root.right.height == 2){
                    if (key.compareTo(root.left.key) < 0)
                        root = LL(root);
                    else
                        root = LR(root);
                }
            }else if(key.compareTo(root.key)>0){
                root.right = insert(root.right,key);
                if(root.left.height - root.right.height == -2){
                    if (key.compareTo(root.right.key) < 0)
                        root = RL(root);
                    else
                        root = RR(root);
                }
            }else{
                return root;//相同的节点不添加
            }
        }
        return root;
    }
    public Node<T> delete(Node<T> root,T key){
        /*
        删除:找到删除点,判断是否需要翻转
         */
        if(root == null || key == null){
            return root;
        }
        else{
            if(key.compareTo(root.key)<0)
            //T是实现了comparable接口的,所以这里可以比较,但不能用大小于号
            {
                root.left = delete(root.left,key);
                if(root.left.height - root.right.height == -2){
                    Node<T> rightNode = root.right;
                    if (rightNode.right.height>root.left.height)
                        root = RL(root);
                    else
                        root = RR(root);
                }
            }else if(key.compareTo(root.key)>0){
                root.right = delete(root.right,key);
                if(root.left.height - root.right.height == 2){
                    Node<T> leftNode = root.left;
                    if (leftNode.left.height>leftNode.right.height)
                        root = LL(root);
                    else
                        root = LR(root);
                }
            }else {
                //找到了要删除的节点
                if (root.left == null) root = root.right;
                else if (root.right == null) root = root.left;
                else {
                    if (root.left.height < root.right.height) {
                        Node<T> tempNode = root.right;
                        while (tempNode.left != null) {
                            tempNode = tempNode.left;
                        }//为保证二叉树的平衡性、搜索性
                        //这里选择了高度较高的子树,选取中序遍历与root相邻的节点作为root,这样不会破坏搜索性
                        root.key = tempNode.key;
                        delete(tempNode, key);
                    } else {
                        Node<T> tempNode = root.left;
                        while (tempNode.right != null) {
                            tempNode = tempNode.right;
                        }//为保证二叉树的平衡性、搜索性
                        //这里选择了高度较高的子树,选取中序遍历与root相邻的节点作为root
                        root.key = tempNode.key;
                        delete(tempNode, key);
                    }
                }
            }
        }
        return root;
    }
}

 

AVL树的Java实现

标签:tno   turn   node   key   class   接口   .com   左右子树   insert   

原文地址:https://www.cnblogs.com/sh1296/p/10326150.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!