您好,欢迎访问一九零五行业门户网

Java数据结构之AVL树详解

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(avl树)的相关知识,avl树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。
推荐学习:《java视频教程》
avl树的引入搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以下极端情况:
这样的二叉树搜索效率甚至比链表还低。在搜索二叉树基础上出现的平衡二叉树(avl树)就解决了这样的问题。当平衡二叉树(avl树)的某个节点左右子树高度差的绝对值大于1时,就会通过旋转操作减小它们的高度差。
基本概念avl树本质上还是一棵二叉搜索树,它的特点是:
本身首先是一棵二叉搜索树。每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。也就是说,avl树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。当插入一个节点或者删除一个节点时,导致某一个节点的左右子树高度差的绝对值大于1,这时需要通过左旋和右旋的操作使二叉树再次达到平衡状态。平衡因子(balancefactor)
一个结点的左子树与右子树的高度之差。avl树中的任意结点的bf只可能是-1,0和1。基础设计下面是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,导致这个树变得不再平衡,此时需要左旋操作,如下:
代码如下:
//左旋,并且返回新的根节点    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,导致这个树变得不再平衡,此时需要左旋操作,如下:
代码如下:
 //右旋,并且返回新的根节点    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.
rl(先右旋再左旋)往avl树右子树的左子树上插入一个节点,导致该树不再平衡,需要先对右子树进行右旋,再对整棵树左旋,如下图所示,插入节点为2.
添加节点//添加元素    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数据结构之avl树详解的详细内容。
其它类似信息

推荐信息