栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

avl树

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

avl树

avl树java实现
public class AvlTree> {

    private AvlTreeNode root;

    private static class AvlTreeNode {
        //要插入的元素
        E ele;
        // 左节点
        AvlTreeNode left;
        // 右节点
        AvlTreeNode right;
        //树的高度,从该节点到树叶节点的最大长度
        int height;

        public AvlTreeNode(E ele, AvlTreeNode right, AvlTreeNode left) {
            this.ele = ele;
            this.right = right;
            this.left = left;
        }
    }

    //定义树的绝对高度
    private final static int ALLOWED_IMBALANCE = 1;

    // 插入元素
    public void insert(E e) {
        root = insert(e, root);
    }

    public boolean isEmpty() {
        return root == null;
    }

    public void printTree() {
        if (isEmpty())
            System.out.println("Empty tree");
        else
            printTree(root);
    }

    private void printTree(AvlTreeNode t) {
        if (t != null) {
            printTree(t.left);
            System.out.println(t.ele);
            printTree(t.right);
        }
    }

    // 益处元素
    public void remove(E e) {
        //需遍历,然后平衡树的结构
        root = remove(e, root);
    }

    //删除节点
    private AvlTreeNode remove(E e, AvlTreeNode node) {
        //根节点为null,说明avl树无元素,直接返回null
        if (node == null) {
            return null;
        }
        int compare = e.compareTo(node.ele);
        if (compare > 0) {
            node.right = remove(e, node.right);
        } else if (compare < 0) {
            node.left = remove(e, node.left);
        } else if (node.left != null && node.right != null) { //删除节点有两个children
            // 这里是我抄的书本,作者设计的很牛,代码如下
            // 首先获取最小节点,将最小节点赋值给当前节点
            node.ele = findMin(node.right).ele;
            //将右children节点中的ele删除
            node.right = remove(node.ele, node.right);
        } else { // 删除的节点仅有一个children
            node = node.left == null ? node.right : node.left;
        }
        return balance(node);
    }

    private AvlTreeNode findMin(AvlTreeNode node) {
        if (node == null) {
            return null;
        }

        while (node.left != null) {
            node = node.left;
        }
        return node;
    }

    
    private AvlTreeNode insert(E e, AvlTreeNode node) {
        //插入第一个元素时,根节点为null
        if (node == null)
            return new AvlTreeNode<>(e, null, null);

        //比较插入的数据
        int i = e.compareTo(node.ele);
        if (i > 0) {
            node.right = insert(e, node.right);
        } else if (i < 0) {
            node.left = insert(e, node.left);
        } else {
            // 元素相同,不做处理
        }
        return balance(node);
    }

    
    private AvlTreeNode balance(AvlTreeNode node) {
        // 删除:当节点为叶子节点时,直接返回null
        if(node==null){
            return null;
        }

        //首先判断当前节点的左节点与右节点的差值大于1
        if (height(node.left) - height(node.right) > ALLOWED_IMBALANCE) {
            // 从左儿子的左节点插入数据,进行单旋转便可
            if (height(node.left.left) >= height(node.left.right)) {
                node = singRightRotate(node);
            } else {
                node = doubleLeftRotate(node);
            }
        } else if (height(node.right) - height(node.left) > ALLOWED_IMBALANCE) {
            // 从右儿子的右节点插入数据,进行单旋转便可
            if (height(node.right.right) >= height(node.right.left)) {
                node = singLeftRotate(node);
            } else {
                node = doubleRightRotate(node);
            }
        }
        node.height = Math.max(height(node.left), height(node.right)) + 1;
        return node;
    }


    // 右旋:从左儿子的左节点插入数据,只有k1、k2两个节点的高度存在变动,
    private AvlTreeNode singRightRotate(AvlTreeNode k2) {
        AvlTreeNode k1 = k2.left;
        k2.left = k1.right;
        k1.right = k2;
        k1.height = Math.max(height(k1.left), height(k1.right)) + 1;
        k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
        return k1;
    }

    // 左旋:从右儿子的右节点插入数据,只有k1、k2两个节点的高度存在变动
    private AvlTreeNode singLeftRotate(AvlTreeNode k1) {
        AvlTreeNode k2 = k1.right;
        k1.right = k2.left;
        k2.left = k1;
        k1.height = Math.max(height(k1.left), height(k1.right)) + 1;
        k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
        return k2;
    }

    //3,从左儿子的右节点插入数据
    private AvlTreeNode doubleLeftRotate(AvlTreeNode node) {
        //先左旋:即node.left.right
        node.left = singLeftRotate(node.left);

        //再右旋:即node.left.right
        return singRightRotate(node);
    }

    // 4,从右儿子的左节点插入数据
    private AvlTreeNode doubleRightRotate(AvlTreeNode node) {
        //先右旋
        node.right = singRightRotate(node.right);
        return singLeftRotate(node);
    }

    //获取当前节点树的高度
    private int height(AvlTreeNode node) {
        return node == null ? -1 : node.height;
    }

}

左旋以及右旋:

道阻且长,行则将至

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/343696.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号