在计算机科学中,AVL树是一种自平衡的二叉搜索树(BST),由 G.M. Adelson-Velsky 和 E.M. Landis 在1962年提出。它的最大特点是:任意节点的左右子树高度差不超过1。这种特性保证了树的高度始终保持在 O(log n),从而使得查找、插入和删除操作的时间复杂度稳定在 O(log n)。
本教程将带你从零开始,用C语言AVL树实现一个完整的自平衡二叉搜索树。无论你是编程新手还是有一定基础的开发者,都能轻松理解并掌握这一经典数据结构。
普通的二叉搜索树在最坏情况下(例如按顺序插入数据)会退化成链表,导致操作效率下降到 O(n)。而AVL树平衡二叉搜索树通过旋转操作自动调整结构,始终保持平衡,避免性能退化。
平衡因子(Balance Factor) = 左子树高度 - 右子树高度。AVL树要求每个节点的平衡因子 ∈ {-1, 0, 1}。
当插入或删除节点导致某节点平衡因子超出范围时,就需要通过旋转来恢复平衡。共有四种旋转情况:
下面我们一步步用C语言实现AVL树。首先定义节点结构:
typedef struct Node { int data; struct Node* left; struct Node* right; int height;} Node; 注意:我们额外存储了 height 字段,用于快速计算平衡因子。
int max(int a, int b) { return (a > b) ? a : b;}int getHeight(Node* node) { if (node == NULL) return -1; // 空节点高度为-1,叶子节点高度为0 return node->height;} // 右旋(LL情况)Node* rotateRight(Node* y) { Node* x = y->left; Node* T2 = x->right; // 执行旋转 x->right = y; y->left = T2; // 更新高度 y->height = max(getHeight(y->left), getHeight(y->right)) + 1; x->height = max(getHeight(x->left), getHeight(x->right)) + 1; return x; // 新的根节点}// 左旋(RR情况)Node* rotateLeft(Node* x) { Node* y = x->right; Node* T2 = y->left; // 执行旋转 y->left = x; x->right = T2; // 更新高度 x->height = max(getHeight(x->left), getHeight(x->right)) + 1; y->height = max(getHeight(y->left), getHeight(y->right)) + 1; return y; // 新的根节点} Node* insert(Node* node, int data) { // 1. 执行标准BST插入 if (node == NULL) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->left = NULL; newNode->right = NULL; newNode->height = 0; return newNode; } if (data < node->data) node->left = insert(node->left, data); else if (data > node->data) node->right = insert(node->right, data); else return node; // 不允许重复值 // 2. 更新当前节点高度 node->height = 1 + max(getHeight(node->left), getHeight(node->right)); // 3. 获取平衡因子 int balance = getHeight(node->left) - getHeight(node->right); // 4. 如果不平衡,进行旋转 // Left Left Case if (balance > 1 && data < node->left->data) return rotateRight(node); // Right Right Case if (balance < -1 && data > node->right->data) return rotateLeft(node); // Left Right Case if (balance > 1 && data > node->left->data) { node->left = rotateLeft(node->left); return rotateRight(node); } // Right Left Case if (balance < -1 && data < node->right->data) { node->right = rotateRight(node->right); return rotateLeft(node); } return node;} 下面是一个简单的主函数,演示如何创建和插入数据到AVL树:
#include <stdio.h>#include <stdlib.h>// ... 上面定义的所有函数 ...void inorder(Node* root) { if (root != NULL) { inorder(root->left); printf("%d ", root->data); inorder(root->right); }}int main() { Node* root = NULL; root = insert(root, 10); root = insert(root, 20); root = insert(root, 30); // 触发左旋 root = insert(root, 40); root = insert(root, 50); root = insert(root, 25); // 触发左右旋转 printf("中序遍历结果(应为有序): "); inorder(root); printf("\n"); return 0;} 通过本教程,你已经掌握了C语言AVL树实现的核心原理和完整代码。AVL树是学习高级数据结构的重要一步,也是面试中常见的考点。希望这份C语言数据结构教程能帮助你打下坚实基础。
记住:AVL树的关键在于自平衡二叉树代码中的旋转逻辑。多动手调试,观察不同插入顺序下的树形变化,你会对平衡机制有更深刻的理解。
现在,你可以尝试扩展功能,比如实现删除操作、查找最小/最大值、或者可视化树结构。祝你编程愉快!
本文由主机测评网于2025-12-13发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025127338.html