二叉树的实现过程

二叉平衡树(AVL树)是一种自平衡二叉搜索树,保证了插入、删除和搜索操作的平均时间复杂度为O(logn)。通过计算节点的平衡因子和执行左旋、右旋、左右旋、右左旋来保持树的平衡。文章详细介绍了四种旋转类型和树的平衡调整方法,并提供了C语言的代码实现。
摘要由CSDN通过智能技术生成

二叉树是一种自平衡二叉搜索树,最初由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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值