平衡二叉树的基本操作

平衡二叉树的概念 

        平衡二叉树(Balanced Binary Tree)是一种特殊的二叉树,它的每个节点的左子树和右子树的高度差不超过1。也就是说,平衡二叉树是一种高度平衡的二叉树,它可以保持在树的高度较小的情况下,实现较快的查找、插入和删除操作。平衡二叉树的一个重要特性是,它的高度是对数级别的,因此在进行查找操作时,时间复杂度为O(log n),其中n为树中节点的个数。这使得平衡二叉树在实际应用中具有较高的效率和性能。常见的平衡二叉树包括AVL树、红黑树等,它们都是通过不同的方式来维护树的平衡性,以确保树的高度始终保持在较小的范围内。在实际应用中,平衡二叉树常常被用作数据存储和索引结构,例如在数据库系统中用于索引数据,以及在编程语言中用于实现各种集合和映射等数据结构。

平衡二叉树的一些术语

平衡因子:在平衡二叉树中,每个节点的平衡因子是指该节点的左子树的高度减去右子树的高度(或者右子树的高度减去左子树的高度)。换句话说,平衡因子是左子树高度和右子树高度之间的差值。如果平衡因子的绝对值大于1,那么这个节点就不平衡。平衡因子为0表示该节点的左右子树高度相等,平衡因子为正数表示左子树高度大于右子树高度,而负数则表示右子树高度大于左子树高度。

右旋:将旧根节点作为新根节点的右子树;如果新根节点(旧根节点的左孩子)原来有右子树,那么将这个右子树作为旧根节点的左子树。

左旋:将旧根节点作为新根节点的左子树;如果新根节点(旧根节点的右孩子)原来有左子树,那么将这个左子树作为旧根节点的右子树。

失衡二叉树的类型及相应的调整

        在插入新节点或者删除旧节点时,可能导致原来的平衡二叉树处于一种“失衡”的状态,这时候就要进行左右旋操作来调整二叉树,使其重新恢复平衡。

下以插入操作为例进行讲解

LL型:插入的节点位于根节点的左孩子的左子树

RR型:插入的节点位于根节点的右孩子的右子树

LR型:插入的节点位于根节点的左孩子的右子树

 RL型:插入节点位于根节点的右孩子的左子树

 平衡二叉树基本操作的代码实现

#include <iostream>
#include <cstdlib>
using namespace std;
struct TreeNode {
    int val;
    int height;
    struct TreeNode* left;
    struct TreeNode* right;
};
int getHeight(struct TreeNode* node) {
    if (node == NULL) {
        return 0;
    }
    return node->height;
}
int getBalanceFactor(struct TreeNode* node) {
    if (node == NULL) {
        return 0;
    }
    return getHeight(node->left) - getHeight(node->right);
}

struct TreeNode* rotateLeft(struct TreeNode* node) {
    struct TreeNode* newRoot = node->right;
    node->right = newRoot->left;
    newRoot->left = node;
    node->height = 1 + max(getHeight(node->left), getHeight(node->right));
    newRoot->height = 1 + max(getHeight(newRoot->left), getHeight(newRoot->right));
    return newRoot;
}

struct TreeNode* rotateRight(struct TreeNode* node) {
    struct TreeNode* newRoot = node->left;
    node->left = newRoot->right;
    newRoot->right = node;
    node->height = 1 + max(getHeight(node->left), getHeight(node->right));
    newRoot->height = 1 + max(getHeight(newRoot->left), getHeight(newRoot->right));
    return newRoot;
}

struct TreeNode* insertNode(struct TreeNode* root, int val) {
    if (root == NULL) {
        struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
        newNode->val = val;
        newNode->height = 1;
        newNode->left = NULL;
        newNode->right = NULL;
        return newNode;
    }
    if (val < root->val) {
        root->left = insertNode(root->left, val);
    } else if (val > root->val) {
        root->right = insertNode(root->right, val);
    } else {
        return root;  // 不允许插入相同的值
    }
    root->height = 1 + max(getHeight(root->left), getHeight(root->right));
    int balanceFactor = getBalanceFactor(root);
    if (balanceFactor > 1 && val < root->left->val) {
        return rotateRight(root);
    }
    if (balanceFactor < -1 && val > root->right->val) {
        return rotateLeft(root);
    }
    if (balanceFactor > 1 && val > root->left->val) {
        root->left = rotateLeft(root->left);
        return rotateRight(root);
    }
    if (balanceFactor < -1 && val < root->right->val) {
        root->right = rotateRight(root->right);
        return rotateLeft(root);
    }
    return root;
}

struct TreeNode* findMin(struct TreeNode* node) {
    while (node->left != NULL) {
        node = node->left;
    }
    return node;
}
struct TreeNode* deleteNode(struct TreeNode* root, int val) {
    if (root == NULL) {
        return NULL;
    }
    if (val < root->val) {
        root->left = deleteNode(root->left, val);
    } else if (val > root->val) {
        root->right = deleteNode(root->right, val);
    } else {
        if (root->left == NULL || root->right == NULL) {
            struct TreeNode* temp = root->left ? root->left : root->right;
            if (temp == NULL) {
                temp = root;
                root = NULL;
            } else {
                *root = *temp;
            }
            free(temp);
        } else {
            struct TreeNode* temp = findMin(root->right);
            root->val = temp->val;
            root->right = deleteNode(root->right, temp->val);
        }
    }
    if (root == NULL) {
        return NULL;
    }
    root->height = 1 + max(getHeight(root->left), getHeight(root->right));
    int balanceFactor = getBalanceFactor(root);
    if (balanceFactor > 1 && getBalanceFactor(root->left) >= 0) {
        return rotateRight(root);
    }
    if (balanceFactor > 1 && getBalanceFactor(root->left) < 0) {
        root->left = rotateLeft(root->left);
        return rotateRight(root);
    }
    if (balanceFactor < -1 && getBalanceFactor(root->right) <= 0) {
        return rotateLeft(root);
    }
    if (balanceFactor < -1 && getBalanceFactor(root->right) > 0) {
        root->right = rotateRight(root->right);
        return rotateLeft(root);
    }
    return root;
}
int main () {
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值