Árbol binario equilibrado
-
Esencialmente una especie de árbol de búsqueda binaria
-
El valor absoluto (factor de equilibrio) de la diferencia de altura entre los subárboles izquierdo y derecho de cada nodo es como máximo 1, | leftTreeHeightmax-rightTreeHeightmax | <= 1
-
diagrama de árbol avi (cuando el subárbol izquierdo o el subárbol derecho, está vacío, el valor predeterminado es -1)
Girar
-
Cuando el factor de equilibrio de avi es mayor que 1, el equilibrio de avi se romperá. En este momento, debemos rotar hacia la izquierda o hacia la derecha para reequilibrarlo.
-
La rotación de AVI se divide en cuatro casos, a saber, tipo izquierda-izquierda, tipo derecha-derecha, tipo izquierda-derecha, tipo derecha-izquierda
-
Tipo de izquierda a izquierda: como en la figura, todos los nodos están sesgados hacia la izquierda, esta vez tenemos que rotar a la derecha
Rotación a la derecha: gire dos nodos en el sentido de las agujas del reloj para que el nodo padre 4 sea reemplazado por el nodo izquierdo 1 y el nodo 4 se convierta en el nodo derecho del nodo 1. ( Resumen: un nodo con un factor de equilibrio de 2 se convierte en el subárbol derecho de su subárbol izquierdo, y el subárbol derecho del subárbol izquierdo original se convierte en su subárbol izquierdo. El factor de equilibrio se actualiza nuevamente )
-
Los nodos de tipo derecho-derecho se concentran en la derecha y se requiere la operación con la mano izquierda ( el punto con un factor de equilibrio de 2 se convierte en el subárbol izquierdo de su subárbol derecho, y el subárbol izquierdo del subárbol derecho original se convierte en su subárbol derecho )
-
Tipo de derecha a izquierda: primero seleccione diestro (conviértalo en tipo de derecha a derecha), luego gírelo para zurdo ( primero conviértalo en tipo de derecha a derecha y luego trate con el tipo de derecha a derecha )
-
Tipo de izquierda a derecha: primero cámbielo a tipo de izquierda a izquierda
public class Node {
int data;
Node lchild;
Node rchild;
int height;
public Node(int data) {
this.data = data;
}
}
public class AVLTree {
private Node root;
// 记录节点的高度
private int height(Node node) {
if (node == null) {
return -1;
} else {
return node.height;
}
}
// 右右型 左旋
private Node L_Rotate(Node node) {
Node temp;
// 进行旋转
temp = node.rchild;
node.rchild = temp.lchild;
temp.lchild = node;
// 重新计算高度
node.height = Math.max(height(node.lchild), height(node.rchild)) + 1;
temp.height = Math.max(height(temp.lchild), height(temp.rchild)) + 1;
return temp;
}
// 左左型 右旋
private Node R_Rotate(Node node) {
Node temp;
// 进行旋转
temp = node.lchild;
node.lchild = temp.rchild;
temp.rchild = node;
// 重新计算高度
node.height = Math.max(height(node.lchild), height(node.rchild)) + 1;
temp.height = Math.max(height(temp.lchild), height(temp.rchild)) + 1;
return temp;
}
// 左右型 先进行左旋在进行右旋
private Node L_R_Rotate(Node node) {
// 对左子节点进行左旋
node.lchild = L_Rotate(node.lchild);
// 对节点进行右旋
return R_Rotate(node);
}
// 右左型 先进性右旋在进行左旋
private Node R_L_Rotate(Node node) {
// 对右子节点进行右旋
node.rchild = R_Rotate(node.rchild);
// 对节点进行左旋
return L_Rotate(node);
}
public void insert(int data) {
root = insert(data, root);
}
// 插入操作
private Node insert(int data, Node node) {
if (node == null) {
node = new Node(data);
} else if (data < node.data) {
// 向左子节点递归插入
node.lchild = insert(data, node.lchild);
// 如果左子节点的高度比右子节点的高度大2 则进行旋转调整
if (height(node.lchild) - height(node.rchild) == 2){
if (data < node.lchild.data) {
// 左左型
node = R_Rotate(node);
} else {
// 左右型
node = R_L_Rotate(node);
}
}
} else if (data > node.data) {
// 向右子节点递归插入
node.rchild = insert(data, node.rchild);
// 如果右子节点的高度比左子节点的高度大2 则进行旋转调整
if (height(node.rchild) - height(node.lchild) == 2) {
if (data > node.rchild.data) {
// 右右型
node = L_Rotate(node);
} else {
// 右左型
node = R_L_Rotate(node);
}
}
}
// 如果 data = node.data 这个节点在树上存在 什么也不做
node.height = Math.max(height(node.lchild), height(node.rchild)) + 1;
return node;
}
// 中序遍历AVL树
public void inOrder() {
inOrder(root);
}
private void inOrder(Node node) {
if (node != null) {
inOrder(node.lchild);
System.out.println(node.data);
inOrder(node.rchild);
}
}
}