文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java平衡二叉树实例分析

2023-06-30 18:05

关注

这篇文章主要讲解了“Java平衡二叉树实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java平衡二叉树实例分析”吧!

AVL树的引入

搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以下极端情况:

Java平衡二叉树实例分析

这样的二叉树搜索效率甚至比链表还低。在搜索二叉树基础上出现的平衡二叉树(AVL树)就解决了这样的问题。当平衡二叉树(AVL树)的某个节点左右子树高度差的绝对值大于1时,就会通过旋转操作减小它们的高度差。

基本概念

AVL树本质上还是一棵二叉搜索树,它的特点是:

平衡因子(balanceFactor)

基础设计

下面是AVL树需要的简单方法和属性:

public class AVLTree <E extends Comparable<E>>{    class Node{        E value;        Node left;        Node right;        int height;        public Node(){}        public Node(E value){            this.value = value;            height = 1;            left = null;            right = null;        }        public void display(){            System.out.print(this.value + " ");        }    }    Node root;    int size;    public int size(){        return size;    }    public int getHeight(Node node) {        if(node == null) return 0;        return node.height;    }    //获取平衡因子(左右子树的高度差,大小为1或者0是平衡的,大小大于1不平衡)    public int getBalanceFactor(){        return getBalanceFactor(root);    }    public int getBalanceFactor(Node node){        if(node == null) return 0;        return getHeight(node.left) - getHeight(node.right);    }    //判断一个树是否是一个平衡二叉树    public boolean isBalance(Node node){        if(node == null) return true;        int balanceFactor = Math.abs(getBalanceFactor(node.left) - getBalanceFactor(node.right));        if(balanceFactor > 1) return false;        return isBalance(node.left) && isBalance(node.right);    }    public boolean isBalance(){        return isBalance(root);    }    //中序遍历树    private  void inPrevOrder(Node root){        if(root == null) return;        inPrevOrder(root.left);        root.display();        inPrevOrder(root.right);    }    public void inPrevOrder(){        System.out.print("中序遍历:");        inPrevOrder(root);    }}

RR(左旋)

往一个树右子树的右子树上插入一个节点,导致二叉树变得不在平衡,如下图,往平衡二叉树中插入5,导致这个树变得不再平衡,此时需要左旋操作,如下:

Java平衡二叉树实例分析

代码如下:

//左旋,并且返回新的根节点    public Node leftRotate(Node node){        System.out.println("leftRotate");       Node cur = node.right;       node.right = cur.left;       cur.left = node;       //跟新node和cur的高度        node.height = Math.max(getHeight(node.left),getHeight(node.right)) + 1;        cur.height = Math.max(getHeight(cur.left),getHeight(cur.right)) + 1;        return cur;    }

LL(右旋)

往一个AVL树左子树的左子树上插入一个节点,导致二叉树变得不在平衡,如下图,往平衡二叉树中插入2,导致这个树变得不再平衡,此时需要左旋操作,如下:

Java平衡二叉树实例分析

代码如下:

 //右旋,并且返回新的根节点    public Node rightRotate(Node node){        System.out.println("rightRotate");        Node cur = node.left;        node.left = cur.right;        cur.right = node;        //跟新node和cur的高度        node.height = Math.max(getHeight(node.left),getHeight(node.right)) + 1;        cur.height = Math.max(getHeight(cur.left),getHeight(cur.right)) + 1;        return cur;    }

LR(先左旋再右旋)

往AVL树左子树的右子树上插入一个节点,导致该树不再平衡,需要先对左子树进行左旋,再对整棵树右旋,如下图所示,插入节点为5.

Java平衡二叉树实例分析

RL(先右旋再左旋)

往AVL树右子树的左子树上插入一个节点,导致该树不再平衡,需要先对右子树进行右旋,再对整棵树左旋,如下图所示,插入节点为2.

Java平衡二叉树实例分析

添加节点

//添加元素    public  void add(E e){        root = add(root,e);    }    public Node add(Node node, E value) {        if (node == null) {            size++;            return new Node(value);        }        if (value.compareTo(node.value) > 0) {            node.right = add(node.right, value);        } else if (value.compareTo(node.value) < 0) {            node.left = add(node.left, value);        }        //跟新节点高度        node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;        //获取当前节点的平衡因子        int balanceFactor = getBalanceFactor(node);        //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的左子树上,此时需要进行右旋        if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) {            return rightRotate(node);        }        //该子树不平衡且新插入节点(导致不平衡的节点)在右子树子树的右子树上,此时需要进行左旋        else if (balanceFactor < -1 && getBalanceFactor(node.right) <= 0) {            return leftRotate(node);        }        //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的右子树上,此时需要先对左子树左旋,在整个树右旋        else if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) {            node.left = leftRotate(node.left);            return rightRotate(node);        }        //balanceFactor < -1 && getBalanceFactor(node.left) > 0        //该子树不平衡且新插入节点(导致不平衡的节点)在右子树的左子树上,此时需要先对右子树右旋,再整个树左旋        else if(balanceFactor < -1 && getBalanceFactor(node.right) > 0) {            node.right = rightRotate(node.right);            return leftRotate(node);        }        return node;    }

删除节点

 //删除节点    public E remove(E value){        root = remove(root,value);        if(root == null){            return null;        }        return root.value;    }    public Node remove(Node node, E value){        Node retNode = null;        if(node == null)            return retNode;        if(value.compareTo(node.value) > 0){            node.right = remove(node.right,value);            retNode = node;        }        else if(value.compareTo(node.value) < 0){            node.left = remove(node.left,value);            retNode = node;        }        //value.compareTo(node.value) = 0        else{            //左右节点都为空,或者左节点为空            if(node.left == null){                size--;                retNode = node.right;            }            //右节点为空            else if(node.right == null){                size--;                retNode = node.left;            }            //左右节点都不为空            else{                Node successor = new Node();                //寻找右子树最小的节点                Node cur = node.right;                while(cur.left != null){                    cur = cur.left;                }                successor.value  = cur.value;                successor.right = remove(node.right,value);                successor.left = node.left;                node.left =  node.right = null;                retNode = successor;            }            if(retNode == null)                return null;            //维护二叉树平衡            //跟新height            retNode.height = Math.max(getHeight(retNode.left),getHeight(retNode.right));        }        int balanceFactor = getBalanceFactor(retNode);        //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的左子树上,此时需要进行右旋        if (balanceFactor > 1 && getBalanceFactor(retNode.left) >= 0) {            return rightRotate(retNode);        }        //该子树不平衡且新插入节点(导致不平衡的节点)在右子树子树的右子树上,此时需要进行左旋        else if (balanceFactor < -1 && getBalanceFactor(retNode.right) <= 0) {            return leftRotate(retNode);        }        //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的右子树上,此时需要先对左子树左旋,在整个树右旋        else if (balanceFactor > 1 && getBalanceFactor(retNode.left) < 0) {            retNode.left = leftRotate(retNode.left);            return rightRotate(retNode);        }        //该子树不平衡且新插入节点(导致不平衡的节点)在右子树的左子树上,此时需要先对右子树右旋,再整个树左旋        else if(balanceFactor < -1 && getBalanceFactor(retNode.right) > 0) {            retNode.right = rightRotate(retNode.right);            return leftRotate(retNode);        }        return  retNode;    }

感谢各位的阅读,以上就是“Java平衡二叉树实例分析”的内容了,经过本文的学习后,相信大家对Java平衡二叉树实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯