二叉树是一种自平衡二叉搜索树,最初由Adelson-Velsky和Landis于1962年引入。它们有时称为AVL树,这是它们发明者姓名的缩写。
二叉平衡树中节点的平衡因子是其左子树高度和右子树高度的差值。如果节点的平衡因子大于1或小于-1,则认为树不平衡,需要重新平衡。这可以通过对树执行一个或多个旋转来实现。
二叉平衡树有四种可能的旋转类型:
1.左旋:用于平衡右子树大于左子树的树。
2.右旋:用于平衡左子树大于右子树的树。
3.左右旋转:用于平衡左子树大于右子树并且左子树的右子树大于左子树的树。
4.右左旋转:用于平衡右子树大于左子树并且右子树的左子树大于右子树的树。
二叉平衡树的平均时间复杂度为O(log n),适用于插入、删除和搜索操作。它们通常用于数据库应用程序以及计算机科学算法和数据结构课程中。
以下是二叉平衡树的实现过程:
定义二叉平衡树节点的结构体,包括键值、左右子树指针和高度等信息。
实现节点高度计算函数,计算节点的高度,如果节点为空则返回-1。
实现节点平衡因子计算函数,计算节点的平衡因子,即左右子树高度之差。
实现单旋转和双旋转函数,用于调整节点位置,使得树的平衡因子满足要求。
实现插入节点函数,首先按照二叉搜索树的规则将节点插入,然后递归调整节点位置,直到树重新平衡。
实现删除节点函数,首先按照二叉搜索树的规则删除节点,然后递归调整节点位置,直到树重新平衡。
以下是二叉平衡树的完整代码实现:
#include <stdio.h>
#include <stdlib.h>
// 定义二叉平衡树节点结构体
typedef struct node {
int key; // 键值
int height; // 高度
struct node* left; // 左子树指针
struct node* right; // 右子树指针
} node;
// 计算节点高度
int height(node* n) {
if (n == NULL) {
return -1;
} else {
return n->height;
}
}
// 计算节点平衡因子
int balance_factor(node* n) {
return height(n->left) - height(n->right);
}
// 左旋转
node* rotate_left(node* n) {
node* new_root = n->right;
n->right = new_root->left;
new_root->left = n;
// 更新高度
n->height = 1 + max(height(n->left), height(n->right));
new_root->height = 1 + max(height(new_root->left), height(new_root->right));
return new_root;
}
// 右旋转
node* rotate_right(node* n) {
node* new_root = n->left;
n->left = new_root->right;
new_root->right = n;
// 更新高度
n->height = 1 + max(height(n->left), height(n->right));
new_root->height = 1 + max(height(new_root->left), height(new_root->right));
return new_root;
}
// 右左旋转
node* rotate_right_left(node* n) {
n->right = rotate_right(n->right);
return rotate_left(n);
}
// 左右旋转
node* rotate_left_right(node* n) {
n->left = rotate_left(n->left);
return rotate_right(n);
}
// 插入节点
node* insert(node* root, int key) {
if (root == NULL) {
// 创建新节点
node* new_node = (node*)malloc(sizeof(node));
new_node->key = key;
new_node->height = 0;
new_node->left = NULL;
new_node->right = NULL;
return new_node;
} else if (key < root->key) {
root->left = insert(root->left, key);
// 调整平衡
if (balance_factor(root) == 2) {
if (key < root->left->key) {
root = rotate_right(root);
} else {
root = rotate_left_right(root);
}
}
} else if (key > root->key) {
root->right = insert(root->right, key);
// 调整平衡
if (balance_factor(root) == -2) {
if (key > root->right->key) {
root = rotate_left(root);
} else {
root = rotate_right_left(root);
}
}
}
// 更新高度
root->height = 1 + max(height(root->left), height(root->right));
return root;
}
// 删除节点
node* delete(node* root, int key) {
if (root == NULL) {
return NULL;
} else if (key < root->key) {
root->left = delete(root->left, key);
} else if (key > root->key) {
root->right = delete(root->right, key);
} else {
if (root->left == NULL && root->right == NULL) {
// 情况1:叶子节点
free(root);
return NULL;
} else if (root->left == NULL || root->right == NULL) {
// 情况2:只有一个子节点
node* temp;
if (root->left == NULL) {
temp = root->right;
} else {
temp = root->left;
}
free(root);
return temp;
} else {
// 情况3:有两个子节点
node* temp = root->right;
while (temp->left != NULL) {
temp = temp->left;
}
root->key = temp->key;
root->right = delete(root->right, temp->key);
}
}
// 调整平衡
if (balance_factor(root) == 2) {
if (balance_factor(root->left) >= 0) {
root = rotate_right(root);
} else {
root = rotate_left_right(root);
}
} else if (balance_factor(root) == -2) {
if (balance_factor(root->right) <= 0) {
root = rotate_left(root);
} else {
root = rotate_right_left(root);
}
}
// 更新高度
root->height = 1 + max(height(root->left), height(root->right));
return root;
}
// 查找节点
node* search(node* root, int key) {
if (root == NULL || root->key == key) {
return root;
} else if (key < root->key) {
return search(root->left, key);
} else {
return search(root->right, key);
}
}
// 中序遍历
void inorder_traversal(node* root) {
if (root != NULL) {
inorder_traversal(root->left);
printf("%d ", root->key);
inorder_traversal(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 Traversal: ");
inorder_traversal(root);
printf("\n");
// 删除节点
root = delete(root, 30);
// 中序遍历
printf("Inorder Traversal: ");
inorder_traversal(root);
printf("\n");
return 0;
}