💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# AVL 树 > 原文: [https://www.programiz.com/dsa/avl-tree](https://www.programiz.com/dsa/avl-tree) #### 在本教程中,您将学习什么是 avl 树。 此外,您还将找到在 C,C++ ,Java 和 Python 的 avl 树上执行的各种操作的工作示例。 AVL 树是一种自平衡二叉搜索树,其中每个节点都维护额外的信息,称为平衡因子,其值为 -1、0 或 +1。 AVL 树以其发明者 Georgy Adelson-Velsky 和 Landis 得名。 * * * ## 平衡系数 AVL 树中节点的平衡因子是该节点的左子树的高度和右子树的高度之间的差。 平衡因子=(左子树的高度-右子树的高度)或(右子树的高度-左子树的高度) Avl 树的自平衡属性由平衡因子保持。 平衡因子的值应始终为 -1、0 或 +1。 平衡 avl 树的示例是: ![avl tree](https://img.kancloud.cn/c9/bb/c9bbb44f57154b2cd29c195b80929c91_688x598.png "avl tree final") Avl tree * * * ## AVL 树上的操作 可以在 AVL 树上执行的各种操作是: ## 旋转 AVL 树中的子树 在旋转操作中,子树的节点位置互换。 轮播有两种类型: * * * ### 向左旋转 在向左旋转时,右侧节点的排列将转换为左侧节点的排列。 算法 1. 令初始树为: ![left-rotate](https://img.kancloud.cn/64/15/64157ab3f620935a30160ff01ec0a719_344x408.png "left rotate") 左旋转 2. 如果`y`具有左子树,则将`x`分配为`y`的左子树的父树。 ![left-rotate](https://img.kancloud.cn/02/1e/021e1bb6aa49047ed0ac070d2462c14c_412x376.png "assign x as the parent of the left subtree of y") 将`x`分配为`y`的左子树的父级 3. 如果`x`的父级是`NULL`,则将`y`作为树的根。 4. 否则,如果`x`是`p`的左子代,则将`y`设为`p`的左子代。 5. 否则,将`y`分配为`p`的右子元素。 ![left-rotate](https://img.kancloud.cn/a9/8f/a98f1c890b3991ba6ef82cc48c295e89_388x304.png "change the parent of x to that of y") 将`x`的父级更改为`y`的父级 6. 将`y`设为`x`的父代。 ![left-rotate](https://img.kancloud.cn/18/b9/18b9bda05676cac83a3bd77346bc3cb8_344x384.png "Assign y as the parent of x.") 将`y`指定为`x`的父代。 * * * ### 向右旋转 在向左旋转时,左侧节点的排列将转换为右侧节点的排列。 1. 令初始树为: ![right-rotate](https://img.kancloud.cn/52/17/52177556bd84f5fc8999fb151b78fe89_344x386.png "initial tree") 初始树 2. 如果`x`具有右子树,则将`y`分配为`x`的右子树的父树。 ![right-rotate](https://img.kancloud.cn/df/e5/dfe5116a1cfe3740846c61becbb251b1_412x386.png "assign y as the parent of the right subtree of x.") 将`y`分配为`x` 的右子树的父级 3. 如果`y`的父级为`NULL`,则将`x`作为树的根。 4. 否则,如果`y`是其父级`p`的右子,则将`x`作为`p`的右子。 5. 否则,将`x`分配为`p`的左子元素。 ![right-rotate](https://img.kancloud.cn/b2/86/b2867f5059619d14cd52ad6080fac2bf_388x314.png "Assign the parent of y as the parent of x.") 将`y`的父级指定为`x`的父级。 6. 使`x`为`y`的父代。 ![right-rotate](https://img.kancloud.cn/6f/b8/6fb8fbfed255059c3ee932bb7db63c6f_344x386.png "assign x as the parent of y") 将`x`分配为`y`的父项 * * * ### 左右旋转 在左右旋转时,首先将布置向左移动,然后向右移动。 1. 在`x-y`上向左旋转。 ![left-right rotate](https://img.kancloud.cn/fb/ef/fbef537af301af5cac6b3529f02b7fc7_856x470.png "left rotate x-y") 向左旋转`x-y` 2. 在`y-z`上向右旋转。 ![left-right rotate](https://img.kancloud.cn/11/cb/11cbdc88e4c368abdaa663dd4f7d80e0_906x470.png "right rotate z-y") 向右旋转`z-y` 在左右旋转时,这些布置首先向右移动,然后向左移动。 1. 在`x-y`上向右旋转。 ![right-left rotate](https://img.kancloud.cn/79/1c/791c8ba947fb0da8ca81ee78b9a9f0a2_882x472.png "right rotate x-y") 右旋转`x-y` 2. 在`z-y`上向左旋转。 ![right-left rotate](https://img.kancloud.cn/4c/a2/4ca2759d7726fa87af3af550f013c2af_902x472.png "left rotate z-y") 向左旋转`z-y` * * * ## 插入新节点的算法 `newNode`始终作为平衡因子等于 0 的叶节点插入。 1. 令初始树为: ![initial tree](https://img.kancloud.cn/1a/ce/1ace8666435de482907c46ad3bec2fde_816x590.png "initial tree for insertion") 插入的初始树 令要插入的节点为: ![new node](https://img.kancloud.cn/aa/dd/aaddd3f7e973d7dcd174e99769b5b403_232x260.png "new node") 新节点 2. 使用以下递归步骤转到相应的叶节点以插入`newNode`。 比较`newKey`与当前树的`rootKey`。 1. 如果`newKey < rootKey`,则在当前节点的左子树上调用插入算法,直到到达叶节点为止。 2. 否则,如果`newKey > rootKey`,则在当前节点的右子树上调用插入算法,直到到达叶节点为止。 3. 否则,返回`leafNode`。 ![avl tree insertion](https://img.kancloud.cn/62/5c/625c5bc8f7f16785a5eef39f720511d3_1084x598.png "finding the location to insert newNode") 查找插入`newNode`的位置 3. 将通过上述步骤获得的`leafKey`与`newKey`进行比较: 1. 如果`newKey < leafKey`,则将`newNode`设为`leafNode`的`leftChild`。 2. 否则,将`newNode`设为`leafNode`的`rightChild`。 ![avl tree insertion](https://img.kancloud.cn/51/ab/51abb4d939f738a6e4590930bb951b23_896x726.png "inserting the new node") 插入新节点 4. 更新节点的`balanceFactor`。 ![avl tree insertion](https://img.kancloud.cn/8c/f6/8cf637d38ff89c7cdd4f9fd7b4bd6f77_816x726.png "updating the balance factor after insertion") 插入后更新平衡因子 5. 如果节点不平衡,请重新平衡该节点。 1. 如果`balanceFactor > 1`,则表示左侧子树的高度大于右侧子树的高度。 因此,请向右旋转或向左旋转 1. 如果`newNodeKey < leftChildKey`进行右旋转。 2. 否则,请左右旋转。 ![insertion in avl tree](https://img.kancloud.cn/df/4e/df4e12df419293c0e99b49c1edd86962_1940x744.png "balancing the tree with rotation") 旋转平衡树 ![insertion in avl tree](https://img.kancloud.cn/8c/23/8c23900b6db324e8bd17074b7a429d24_1848x722.png "balancing the tree with rotation") 旋转平衡树 2. 如果`balanceFactor < -1`,则意味着右子树的高度大于左子树的高度。 因此,请向右旋转或向左旋转 1. 如果`newNodeKey > rightChildKey`进行左旋转。 2. 否则,请左右旋转 6. 最终的树是: ![left-right insertion](https://img.kancloud.cn/c7/45/c745ba1b8d67b8ed5f154d42cf821e63_816x598.png "final balanced tree") 最终的平衡树 * * * ## 删除节点的算法 节点始终被删除为叶节点。 删除节点后,节点的平衡因子将更改。 为了重新平衡平衡系数,执行适当的旋转。 1. 找到`nodeToBeDeleted`(递归用于在下面使用的代码中找到`nodeToBeDeleted`)。 ![node to be deleted](https://img.kancloud.cn/0f/32/0f32c4e9897183b433c50892cba41fe1_816x598.png "locating the node to be deleted") 定位要删除的节点 2. 删除节点有以下三种情况: 1. 如果`nodeToBeDeleted`是叶节点(即没有任何子节点),则删除`nodeToBeDeleted`。 2. 如果`nodeToBeDeleted`有一个子级,则用该子级的内容替换`nodeToBeDeleted`的内容。 移走子级。 3. 如果`nodeToBeDeleted`有两个子级,则找到`nodeToBeDeleted`的有序继承人`w`(即,在右子树中具有键的最小值的节点)。 ![finding the successor](https://img.kancloud.cn/39/b0/39b057f52c23d3898769aa9c4b2d279a_816x598.png "finding the successor") 寻找继任者 1. 将`nodeToBeDeleted`的内容替换为`w`的内容。 ![substitute the node to be deleted](https://img.kancloud.cn/c7/04/c70401b404f72ec18f5eea092d020ccb_954x616.png "substitute the node to be deleted") 替换要删除的节点 2. 删除叶节点`w`。 ![remove w](https://img.kancloud.cn/7b/b6/7bb62c8fd26b1566ba5b68fb4d60d3c7_816x598.png "remove w") 移除 3. 更新节点的`balanceFactor`。 ![update bf](https://img.kancloud.cn/d7/3b/d73bf486a780dddb46f4dff3f2efce6f_816x598.png "update bf") 更新`bf` 4. 如果任何节点的平衡因子不等于 -1、0 或 1,则重新平衡树。 1. 如果`currentNode > balanceFactor`, 1. 如果`leftChild`的`balanceFactor >= 0`,请向右旋转。 ![right-rotate](https://img.kancloud.cn/9d/a8/9da84ff7d3eea535977ef99006d9167e_1592x598.png "right-rotate for balancing the tree") 向右旋转以平衡树 2. 否则做左右旋转。 2. 如果`currentNode`的`balanceFactor < -1`, 1. 如果`rightChild`的`balanceFactor = 0`,请向左旋转。 2. 否则做左右旋转。 5. 最终的树是: ![avl tree](https://img.kancloud.cn/c9/bb/c9bbb44f57154b2cd29c195b80929c91_688x598.png "avl tree final") Avl 最终树 * * * ## Python,Java 和 C/C++ 示例 ```py # 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) ``` ```java // 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.left = rightRotate(node.left); 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); } } ``` ```c // 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 getBalanceFactor(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 insert the node and insert 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 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->left = rightRotate(node->left); 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 node 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 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 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, 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); printPreOrder(root); root = deleteNode(root, 13); printf("\nAfter deletion: "); printPreOrder(root); } ``` ```cpp // 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->left = rightRotate(node->left); 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 树应用 * 用于索引数据库中的大记录 * 用于在大型数据库中搜索