Heim  >  Artikel  >  Java  >  Beispielanalyse der Java-Datenstruktur AVL-Baum

Beispielanalyse der Java-Datenstruktur AVL-Baum

王林
王林nach vorne
2023-04-29 22:07:051259Durchsuche

Beispielanalyse der Java-Datenstruktur AVL-Baum

Die Einführung von AVL-Bäumen

Das Durchsuchen von Binärbäumen hat eine extrem hohe Sucheffizienz, aber das Durchsuchen von Binärbäumen führt zu den folgenden Extremsituationen:
Beispielanalyse der Java-Datenstruktur AVL-Baum
Die Sucheffizienz solcher Binärbäume ist noch geringer als die von verknüpften Listen. Der ausgeglichene Binärbaum (AVL-Baum), der basierend auf dem Suchbinärbaum erscheint, löst dieses Problem. Wenn der Absolutwert des Höhenunterschieds zwischen dem linken und dem rechten Teilbaum eines Knotens in einem ausgeglichenen Binärbaum (AVL-Baum) größer als 1 ist, wird der Höhenunterschied durch eine Rotationsoperation verringert.

Grundkonzept

Der AVL-Baum ist im Wesentlichen ein binärer Suchbaum. Seine Eigenschaften sind:

  1. selbst ist zunächst einmal ein binärer Suchbaum. 二叉搜索树

  2. 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。

  3. 当插入一个节点或者删除一个节点时,导致某一个节点的左右子树高度差的绝对值大于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,导致这个树变得不再平衡,此时需要左旋操作,如下:
Beispielanalyse der Java-Datenstruktur AVL-Baum
代码如下:

//左旋,并且返回新的根节点
    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,导致这个树变得不再平衡,此时需要左旋操作,如下:
Beispielanalyse der Java-Datenstruktur AVL-Baum
代码如下:

 //右旋,并且返回新的根节点
    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.
Beispielanalyse der Java-Datenstruktur AVL-Baum

RL(先右旋再左旋)

往AVL树右子树的左子树上插入一个节点,导致该树不再平衡,需要先对右子树进行右旋,再对整棵树左旋
Beispielanalyse der Java-Datenstruktur AVL-BaumDer absolute Wert (Balancefaktor) des Höhenunterschieds zwischen dem linken und rechten Teilbaum jedes Knotens beträgt höchstens 1. Mit anderen Worten, der AVL-Baum ist im Wesentlichen ein binärer Suchbaum (binärer Sortierbaum, binärer Suchbaum) mit Balance-Funktion.

Beim Einfügen eines Knotens oder Löschen eines Knotens ist der absolute Wert des Höhenunterschieds zwischen dem linken und rechten Teilbaum eines Knotens größer als 1. In diesem Fall Linksdrehung und Rechtsrotation sind erforderlich. Durch die Rotationsoperation erreicht der Binärbaum wieder einen ausgeglichenen Zustand. <h3></h3> <strong>Balance Factor (balanceFactor)</strong>🎜<ul class=" list-paddingleft-2">🎜🎜Der linke Teilbaum und der rechte Teilbaum eines KnotensHöhe Unterschied</ul>. 🎜🎜🎜Der BF eines beliebigen Knotens im AVL-Baum kann nur -1, 0 und 1 sein. 🎜🎜Grundlegendes Design🎜🎜Die folgenden einfachen Methoden und Attribute sind für den AVL-Baum erforderlich: 🎜
//添加元素
    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;
    }
🎜RR (Linksdrehung)🎜🎜In den rechten Teilbaum der rechten Seite einfügen Teilbaum eines Baums Ein Knoten führt dazu, dass der Binärbaum aus dem Gleichgewicht gerät. Wie in der folgenden Abbildung gezeigt, führt das Einfügen von 5 in den ausgeglichenen Binärbaum dazu, dass der Baum wie folgt aus dem Gleichgewicht gerät. 🎜Java Data Structure AVL Tree Beispielanalyse🎜 Der Code lautet wie folgt: 🎜
 //删除节点
    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;
    }
🎜LL (Rechtsdrehung)🎜🎜Nach links eines AVL-Baums Das Einfügen eines Knotens in den linken Teilbaum des Teilbaums führt dazu, dass der Binärbaum unausgeglichen wird, wie in der Abbildung unten gezeigt Zu diesem Zeitpunkt ist eine Linkskurve wie folgt erforderlich: 🎜Java Data Structure AVL Tree Instance Analysis🎜 Der Code lautet wie folgt: 🎜rrreee🎜LR (Zuerst nach links drehen, dann nach rechts drehen)🎜🎜Fügen Sie einen Knoten in den rechten Teilbaum des linken Teilbaums ein des AVL-Baums, was dazu führt, dass der Baum nicht mehr ausgeglichen ist. Sie müssen zuerst eine Linksdrehung am linken Teilbaum durchführen und dann den gesamten Baum nach rechts drehen, wie in der Abbildung unten gezeigt, Knoten 5 einfügen.🎜<img src="https://img.php.cn/upload/article/000/465/%20014/168277722832272.jpg" alt="Java-Daten Struktur AVL-Baum Beispielanalyse">🎜🎜RL (zuerst rechts und dann links)🎜🎜Gehe zum linken Teilbaum des AVL-Baums <code>rechter Teilbaum Das Einfügen eines Knotens führt dazu, dass der Baum nicht mehr ausgeglichen ist. Sie müssen zuerst den rechten Teilbaum nach rechts und dann den gesamten Baum nach links drehen. Wie in der Abbildung unten gezeigt, ist der eingefügte Knoten 2.🎜 🎜🎜🎜Knoten hinzufügen🎜rrreee🎜Knoten löschen🎜rrreee

Das obige ist der detaillierte Inhalt vonBeispielanalyse der Java-Datenstruktur AVL-Baum. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen