AVL 树是一种自平衡二叉搜索树,其中每个节点都维护额外的信息,称为平衡因子,其值可以是 -1、0 或 +1。
AVL 树的名字来源于其发明者 Georgy Adelson-Velsky 和 Landis。
平衡因子
AVL 树中节点的平衡因子是该节点左子树的高度与右子树高度之差。
平衡因子 = (左子树高度 - 右子树高度) 或 (右子树高度 - 左子树高度)
AVL 树的自平衡特性由平衡因子来维持。平衡因子的值应始终为 -1、0 或 +1。
平衡的 AVL 树示例

AVL 树上的操作
AVL 树上可以执行的各种操作有:
AVL 树中子树的旋转
在旋转操作中,子树节点的顺序会互换。
有两种类型的旋转:
左旋
在左旋中,右侧节点的排列方式转换为左侧节点的排列方式。
算法
- 设初始树为
左旋 - 如果 y 有左子树,将 y 的左子树的父节点设为 x。
将 y 的左子树的父节点设为 x - 如果 x 的父节点为
NULL
,将 y 设为树的根节点。 - 否则,如果 x 是 p 的左子节点,则将 y 设为 p 的左子节点。
- 否则,将 y 设为 p 的右子节点。
将 x 的父节点更改为 y 的父节点 - 将 x 的父节点设为 y。
将 x 的父节点设为 y。
右旋
在右旋中,左侧节点的排列方式转换为右侧节点的排列方式。
- 设初始树为
初始树 - 如果 x 有右子树,将 x 的右子树的父节点设为 y。
将 x 的右子树的父节点设为 y - 如果 y 的父节点为
NULL
,将 x 设为树的根节点。 - 否则,如果 y 是其父节点 p 的右子节点,则将 x 设为 p 的右子节点。
- 否则,将 x 设为 p 的左子节点。
将 y 的父节点设为 x 的父节点。 - 将 y 的父节点设为 x。
将 y 的父节点设为 x
左右旋和右左旋
在左右旋中,排列方式先向左移动,然后向右移动。
- 对 x-y 进行左旋。
左旋 x-y - 对 y-z 进行右旋。
右旋 z-y
在右左旋中,排列方式先向右移动,然后向左移动。
- 对 x-y 进行右旋。
右旋 x-y - 对 z-y 进行左旋。
左旋 z-y
插入新节点的算法
一个 newNode 始终作为叶节点插入,平衡因子为 0。
- 设初始树为
用于插入的初始树
设要插入的节点为新节点 - 使用以下递归步骤,转到合适的叶节点以插入 newNode。将 newKey 与当前树的 rootKey 进行比较。
- 如果 newKey < rootKey,则对当前节点的左子树调用插入算法,直到到达叶节点。
- 否则,如果 newKey > rootKey,则对当前节点的右子树调用插入算法,直到到达叶节点。
- 否则,返回 leafNode。
查找插入 newNode 的位置
- 将上述步骤得到的 leafKey 与 newKey 进行比较。
- 如果 newKey < leafKey,则将 newNode 设为 leafNode 的 leftChild。
- 否则,将 newNode 设为 leafNode 的 rightChild。
插入新节点
- 更新节点的 balanceFactor。
插入后更新平衡因子 - 如果节点不平衡,则重新平衡节点。
- 如果 balanceFactor > 1,则表示左子树的高度大于右子树的高度。因此,执行右旋或左右旋。
- 如果 newNodeKey < leftChildKey,则执行右旋。
- 否则,执行左右旋。
通过旋转平衡树 通过旋转平衡树
- 如果 balanceFactor < -1,则表示右子树的高度大于左子树的高度。因此,执行右旋或右左旋。
- 如果 newNodeKey > rightChildKey,则执行左旋。
- 否则,执行右左旋。
- 如果 balanceFactor > 1,则表示左子树的高度大于右子树的高度。因此,执行右旋或左右旋。
- 最终的树是
最终平衡树
删除节点的算法
节点始终作为叶节点删除。删除节点后,节点的平衡因子会发生变化。为了重新平衡平衡因子,会执行适当的旋转。
- 定位 nodeToBeDeleted(代码中使用递归来查找 nodeToBeDeleted)。
定位要删除的节点 - 删除节点有三种情况:
- 如果 nodeToBeDeleted 是叶节点(即没有子节点),则删除 nodeToBeDeleted。
- 如果 nodeToBeDeleted 有一个子节点,则将 nodeToBeDeleted 的内容替换为其子节点的内容。删除子节点。
- 如果 nodeToBeDeleted 有两个子节点,则找到 nodeToBeDeleted 的中序后继 w(即右子树中键值最小的节点)。
查找后继 - 将 nodeToBeDeleted 的内容替换为 w 的内容。
替换要删除的节点 - 删除叶节点 w。
删除 w
- 将 nodeToBeDeleted 的内容替换为 w 的内容。
- 更新节点的 balanceFactor。
更新 bf - 如果任何节点的平衡因子不等于 -1、0 或 1,则重新平衡树。
- 如果 currentNode 的 balanceFactor > 1,
- 如果 leftChild 的 balanceFactor >= 0,则执行右旋。
右旋以平衡树 - 否则,执行左右旋。
- 如果 leftChild 的 balanceFactor >= 0,则执行右旋。
- 如果 currentNode 的 balanceFactor < -1,
- 如果 rightChild 的 balanceFactor <= 0,则执行左旋。
- 否则,执行右左旋。
- 如果 currentNode 的 balanceFactor > 1,
- 最终的树是
AVL 树最终
Python、Java 和 C/C++ 示例
# AVL tree implementation in Python
import sys
# Create a tree node
class TreeNode(object):
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.height = 1
class AVLTree(object):
# Function to insert a node
def insert_node(self, root, key):
# Find the correct location and insert the node
if not root:
return TreeNode(key)
elif key < root.key:
root.left = self.insert_node(root.left, key)
else:
root.right = self.insert_node(root.right, key)
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
# Update the balance factor and balance the tree
balanceFactor = self.getBalance(root)
if balanceFactor > 1:
if key < root.left.key:
return self.rightRotate(root)
else:
root.left = self.leftRotate(root.left)
return self.rightRotate(root)
if balanceFactor < -1:
if key > root.right.key:
return self.leftRotate(root)
else:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
# Function to delete a node
def delete_node(self, root, key):
# Find the node to be deleted and remove it
if not root:
return root
elif key < root.key:
root.left = self.delete_node(root.left, key)
elif key > root.key:
root.right = self.delete_node(root.right, key)
else:
if root.left is None:
temp = root.right
root = None
return temp
elif root.right is None:
temp = root.left
root = None
return temp
temp = self.getMinValueNode(root.right)
root.key = temp.key
root.right = self.delete_node(root.right,
temp.key)
if root is None:
return root
# Update the balance factor of nodes
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
balanceFactor = self.getBalance(root)
# Balance the tree
if balanceFactor > 1:
if self.getBalance(root.left) >= 0:
return self.rightRotate(root)
else:
root.left = self.leftRotate(root.left)
return self.rightRotate(root)
if balanceFactor < -1:
if self.getBalance(root.right) <= 0:
return self.leftRotate(root)
else:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
# Function to perform left rotation
def leftRotate(self, z):
y = z.right
T2 = y.left
y.left = z
z.right = T2
z.height = 1 + max(self.getHeight(z.left),
self.getHeight(z.right))
y.height = 1 + max(self.getHeight(y.left),
self.getHeight(y.right))
return y
# Function to perform right rotation
def rightRotate(self, z):
y = z.left
T3 = y.right
y.right = z
z.left = T3
z.height = 1 + max(self.getHeight(z.left),
self.getHeight(z.right))
y.height = 1 + max(self.getHeight(y.left),
self.getHeight(y.right))
return y
# Get the height of the node
def getHeight(self, root):
if not root:
return 0
return root.height
# Get balance factore of the node
def getBalance(self, root):
if not root:
return 0
return self.getHeight(root.left) - self.getHeight(root.right)
def getMinValueNode(self, root):
if root is None or root.left is None:
return root
return self.getMinValueNode(root.left)
def preOrder(self, root):
if not root:
return
print("{0} ".format(root.key), end="")
self.preOrder(root.left)
self.preOrder(root.right)
# Print the tree
def printHelper(self, currPtr, indent, last):
if currPtr != None:
sys.stdout.write(indent)
if last:
sys.stdout.write("R----")
indent += " "
else:
sys.stdout.write("L----")
indent += "| "
print(currPtr.key)
self.printHelper(currPtr.left, indent, False)
self.printHelper(currPtr.right, indent, True)
myTree = AVLTree()
root = None
nums = [33, 13, 52, 9, 21, 61, 8, 11]
for num in nums:
root = myTree.insert_node(root, num)
myTree.printHelper(root, "", True)
key = 13
root = myTree.delete_node(root, key)
print("After Deletion: ")
myTree.printHelper(root, "", True)
// AVL tree implementation in Java
// Create node
class Node {
int item, height;
Node left, right;
Node(int d) {
item = d;
height = 1;
}
}
// Tree class
class AVLTree {
Node root;
int height(Node N) {
if (N == null)
return 0;
return N.height;
}
int max(int a, int b) {
return (a > b) ? a : b;
}
Node rightRotate(Node y) {
Node x = y.left;
Node T2 = x.right;
x.right = y;
y.left = T2;
y.height = max(height(y.left), height(y.right)) + 1;
x.height = max(height(x.left), height(x.right)) + 1;
return x;
}
Node leftRotate(Node x) {
Node y = x.right;
Node T2 = y.left;
y.left = x;
x.right = T2;
x.height = max(height(x.left), height(x.right)) + 1;
y.height = max(height(y.left), height(y.right)) + 1;
return y;
}
// Get balance factor of a node
int getBalanceFactor(Node N) {
if (N == null)
return 0;
return height(N.left) - height(N.right);
}
// Insert a node
Node insertNode(Node node, int item) {
// Find the position and insert the node
if (node == null)
return (new Node(item));
if (item < node.item)
node.left = insertNode(node.left, item);
else if (item > node.item)
node.right = insertNode(node.right, item);
else
return node;
// Update the balance factor of each node
// And, balance the tree
node.height = 1 + max(height(node.left), height(node.right));
int balanceFactor = getBalanceFactor(node);
if (balanceFactor > 1) {
if (item < node.left.item) {
return rightRotate(node);
} else if (item > node.left.item) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
}
if (balanceFactor < -1) {
if (item > node.right.item) {
return leftRotate(node);
} else if (item < node.right.item) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
}
return node;
}
Node nodeWithMimumValue(Node node) {
Node current = node;
while (current.left != null)
current = current.left;
return current;
}
// Delete a node
Node deleteNode(Node root, int item) {
// Find the node to be deleted and remove it
if (root == null)
return root;
if (item < root.item)
root.left = deleteNode(root.left, item);
else if (item > root.item)
root.right = deleteNode(root.right, item);
else {
if ((root.left == null) || (root.right == null)) {
Node temp = null;
if (temp == root.left)
temp = root.right;
else
temp = root.left;
if (temp == null) {
temp = root;
root = null;
} else
root = temp;
} else {
Node temp = nodeWithMimumValue(root.right);
root.item = temp.item;
root.right = deleteNode(root.right, temp.item);
}
}
if (root == null)
return root;
// Update the balance factor of each node and balance the tree
root.height = max(height(root.left), height(root.right)) + 1;
int balanceFactor = getBalanceFactor(root);
if (balanceFactor > 1) {
if (getBalanceFactor(root.left) >= 0) {
return rightRotate(root);
} else {
root.left = leftRotate(root.left);
return rightRotate(root);
}
}
if (balanceFactor < -1) {
if (getBalanceFactor(root.right) <= 0) {
return leftRotate(root);
} else {
root.right = rightRotate(root.right);
return leftRotate(root);
}
}
return root;
}
void preOrder(Node node) {
if (node != null) {
System.out.print(node.item + " ");
preOrder(node.left);
preOrder(node.right);
}
}
// Print the tree
private void printTree(Node currPtr, String indent, boolean last) {
if (currPtr != null) {
System.out.print(indent);
if (last) {
System.out.print("R----");
indent += " ";
} else {
System.out.print("L----");
indent += "| ";
}
System.out.println(currPtr.item);
printTree(currPtr.left, indent, false);
printTree(currPtr.right, indent, true);
}
}
// Driver code
public static void main(String[] args) {
AVLTree tree = new AVLTree();
tree.root = tree.insertNode(tree.root, 33);
tree.root = tree.insertNode(tree.root, 13);
tree.root = tree.insertNode(tree.root, 53);
tree.root = tree.insertNode(tree.root, 9);
tree.root = tree.insertNode(tree.root, 21);
tree.root = tree.insertNode(tree.root, 61);
tree.root = tree.insertNode(tree.root, 8);
tree.root = tree.insertNode(tree.root, 11);
tree.printTree(tree.root, "", true);
tree.root = tree.deleteNode(tree.root, 13);
System.out.println("After Deletion: ");
tree.printTree(tree.root, "", true);
}
}
// AVL tree implementation in C
#include <stdio.h>
#include <stdlib.h>
// Create Node
struct Node {
int key;
struct Node *left;
struct Node *right;
int height;
};
int max(int a, int b);
// Calculate height
int height(struct Node *N) {
if (N == NULL)
return 0;
return N->height;
}
int max(int a, int b) {
return (a > b) ? a : b;
}
// Create a node
struct Node *newNode(int key) {
struct Node *node = (struct Node *)
malloc(sizeof(struct Node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return (node);
}
// Right rotate
struct Node *rightRotate(struct Node *y) {
struct Node *x = y->left;
struct Node *T2 = x->right;
x->right = y;
y->left = T2;
y->height = max(height(y->left), height(y->right)) + 1;
x->height = max(height(x->left), height(x->right)) + 1;
return x;
}
// Left rotate
struct Node *leftRotate(struct Node *x) {
struct Node *y = x->right;
struct Node *T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
return y;
}
// Get the balance factor
int getBalance(struct Node *N) {
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
// Insert node
struct Node *insertNode(struct Node *node, int key) {
// Find the correct position to insertNode the node and insertNode it
if (node == NULL)
return (newNode(key));
if (key < node->key)
node->left = insertNode(node->left, key);
else if (key > node->key)
node->right = insertNode(node->right, key);
else
return node;
// Update the balance factor of each node and
// Balance the tree
node->height = 1 + max(height(node->left),
height(node->right));
int balance = getBalance(node);
if (balance > 1 && key < node->left->key)
return rightRotate(node);
if (balance < -1 && key > node->right->key)
return leftRotate(node);
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
struct Node *minValueNode(struct Node *node) {
struct Node *current = node;
while (current->left != NULL)
current = current->left;
return current;
}
// Delete a nodes
struct Node *deleteNode(struct Node *root, int key) {
// Find the node and delete it
if (root == NULL)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
if ((root->left == NULL) || (root->right == NULL)) {
struct Node *temp = root->left ? root->left : root->right;
if (temp == NULL) {
temp = root;
root = NULL;
} else
*root = *temp;
free(temp);
} else {
struct Node *temp = minValueNode(root->right);
root->key = temp->key;
root->right = deleteNode(root->right, temp->key);
}
}
if (root == NULL)
return root;
// Update the balance factor of each node and
// balance the tree
root->height = 1 + max(height(root->left),
height(root->right));
int balance = getBalance(root);
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
// Print the tree
void printPreOrder(struct Node *root) {
if (root != NULL) {
printf("%d ", root->key);
printPreOrder(root->left);
printPreOrder(root->right);
}
}
int main() {
struct Node *root = NULL;
root = insertNode(root, 2);
root = insertNode(root, 1);
root = insertNode(root, 7);
root = insertNode(root, 4);
root = insertNode(root, 5);
root = insertNode(root, 3);
root = insertNode(root, 8);
printPreOrder(root);
root = deleteNode(root, 3);
printf("\nAfter deletion: ");
printPreOrder(root);
return 0;
}
// AVL tree implementation in C++
#include <iostream>
using namespace std;
class Node {
public:
int key;
Node *left;
Node *right;
int height;
};
int max(int a, int b);
// Calculate height
int height(Node *N) {
if (N == NULL)
return 0;
return N->height;
}
int max(int a, int b) {
return (a > b) ? a : b;
}
// New node creation
Node *newNode(int key) {
Node *node = new Node();
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return (node);
}
// Rotate right
Node *rightRotate(Node *y) {
Node *x = y->left;
Node *T2 = x->right;
x->right = y;
y->left = T2;
y->height = max(height(y->left),
height(y->right)) +
1;
x->height = max(height(x->left),
height(x->right)) +
1;
return x;
}
// Rotate left
Node *leftRotate(Node *x) {
Node *y = x->right;
Node *T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left),
height(x->right)) +
1;
y->height = max(height(y->left),
height(y->right)) +
1;
return y;
}
// Get the balance factor of each node
int getBalanceFactor(Node *N) {
if (N == NULL)
return 0;
return height(N->left) -
height(N->right);
}
// Insert a node
Node *insertNode(Node *node, int key) {
// Find the correct postion and insert the node
if (node == NULL)
return (newNode(key));
if (key < node->key)
node->left = insertNode(node->left, key);
else if (key > node->key)
node->right = insertNode(node->right, key);
else
return node;
// Update the balance factor of each node and
// balance the tree
node->height = 1 + max(height(node->left),
height(node->right));
int balanceFactor = getBalanceFactor(node);
if (balanceFactor > 1) {
if (key < node->left->key) {
return rightRotate(node);
} else if (key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
}
if (balanceFactor < -1) {
if (key > node->right->key) {
return leftRotate(node);
} else if (key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
}
return node;
}
// Node with minimum value
Node *nodeWithMimumValue(Node *node) {
Node *current = node;
while (current->left != NULL)
current = current->left;
return current;
}
// Delete a node
Node *deleteNode(Node *root, int key) {
// Find the node and delete it
if (root == NULL)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
if ((root->left == NULL) ||
(root->right == NULL)) {
Node *temp = root->left ? root->left : root->right;
if (temp == NULL) {
temp = root;
root = NULL;
} else
*root = *temp;
free(temp);
} else {
Node *temp = nodeWithMimumValue(root->right);
root->key = temp->key;
root->right = deleteNode(root->right,
temp->key);
}
}
if (root == NULL)
return root;
// Update the balance factor of each node and
// balance the tree
root->height = 1 + max(height(root->left),
height(root->right));
int balanceFactor = getBalanceFactor(root);
if (balanceFactor > 1) {
if (getBalanceFactor(root->left) >= 0) {
return rightRotate(root);
} else {
root->left = leftRotate(root->left);
return rightRotate(root);
}
}
if (balanceFactor < -1) {
if (getBalanceFactor(root->right) <= 0) {
return leftRotate(root);
} else {
root->right = rightRotate(root->right);
return leftRotate(root);
}
}
return root;
}
// Print the tree
void printTree(Node *root, string indent, bool last) {
if (root != nullptr) {
cout << indent;
if (last) {
cout << "R----";
indent += " ";
} else {
cout << "L----";
indent += "| ";
}
cout << root->key << endl;
printTree(root->left, indent, false);
printTree(root->right, indent, true);
}
}
int main() {
Node *root = NULL;
root = insertNode(root, 33);
root = insertNode(root, 13);
root = insertNode(root, 53);
root = insertNode(root, 9);
root = insertNode(root, 21);
root = insertNode(root, 61);
root = insertNode(root, 8);
root = insertNode(root, 11);
printTree(root, "", true);
root = deleteNode(root, 13);
cout << "After deleting " << endl;
printTree(root, "", true);
}
AVL 树不同操作的复杂度
插入 | 删除 | 搜索 |
O(log n) | O(log n) | O(log n) |
AVL 树的应用
- 用于数据库中的大型记录索引
- 用于大型数据库的搜索