AVL树(基本操作代码)

 四种旋转

// 定义一个结构体表示树节点
struct Node {
    int key;    // 节点关键字值/key值
    int height; // 节点的高度,用于AVL树的平衡因子计算
    Node* left; // 指向左子树的指针
    Node* right;// 指向右子树的指针
};

// 获取树的高度函数
// 如果节点为NULL,则高度为0,否则返回节点的高度值
int height(Node* N) {
    if (N == NULL)
        return 0;
    return N->height;
}

// 创建新节点函数
// 输入关键字值,初始化一个新节点,并返回它的指针
Node* newNode(int key)
{
    Node* node = new Node(); // 创建新节点
    node->key = key;         // 设置新节点的关键字值
    node->left = NULL;       // 设置新节点左子树为NULL
    node->right = NULL;      // 设置新节点右子树为NULL
    node->height = 1;        // 新节点初建时是叶子节点,高度为1
    return(node);            // 返回新节点的指针
}
// 获取两个整数的最大值
int max(int a, int b) {
    return (a > b) ? a : b;
}

// 计算平衡因子函数
// 用于检测树是否失衡
int getBalance(Node* N) {
    if (N == NULL)
        return 0;
    return height(N->left) - height(N->right);
}

// 添加节点
Node* insert(Node* node, int key) {
    // 1. 正常的二叉搜索树插入操作
    if (node == NULL) {
        return(newNode(key)); // 创建新节点并返回
    }

    if (key < node->key) {
        node->left = insert(node->left, key); // 插入左子树中
    }
    else if (key > node->key) {
        node->right = insert(node->right, key); // 插入右子树中
    }
    else {
        // 相等的key值,不允许插入重复元素
        return node;
    }

    // 2. 更新节点高度
    node->height = 1 + max(height(node->left), height(node->right));

    // 3. 检查节点平衡因子,确定是否需要旋转
    int balance = getBalance(node); // 计算平衡因子

    // 根据平衡因子决定旋转策略
    // 左子树高度大于右子树高度,且插入的节点在左字树的左边 -- LL
    if (balance > 1 && key < node->left->key) {
        return rightRotate(node); // 右旋
    }

    // 右子树高度大于左子树高度,且插入的节点在右子树的右边 -- RR
    if (balance < -1 && key > node->right->key) {
        return leftRotate(node); // 左旋
    }

    // 左子树高度大于右子树高度,且插入的节点在左子树的右边 -- LR
    if (balance > 1 && key > node->left->key) {
        return LRrotate(node); // 左-右旋
    }

    // 右子树高度大于左子树高度,且插入的节点在右子树的左边 -- RL
    if (balance < -1 && key < node->right->key) {
        return RLrotate(node); // 右-左旋
    }

    // 插入之后仍然平衡,无需旋转,直接返回该节点
    return node;
}
// 右旋操作函数
// 输入当前节点y,返回旋转后新的根节点
Node* rightRotate(Node* y) {
    Node* x = y->left;       // 保存y的左子树节点
    Node* T2 = x->right;     // 保存x的右子树

    // 旋转操作
    x->right = y;            // 把y设为x的右子树
    y->left = T2;            // 把T2设为y的左子树

    // 更新节点的高度
    // 高度等于节点的左、右子树的最大高度 + 1
    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和y节点的高度
    x->height = max(height(x->left),height(x->right)) + 1;
    y->height = max(height(y->left),height(y->right)) + 1;

    // 返回新的根节点
    return y;
}

// 左右旋操作函数 LR
// 先对节点的左子树进行左旋操作,再对节点自身进行右旋操作
Node* LRrotate(Node* node) {
    node->left = leftRotate(node->left);    // 对节点的左子树进行左旋操作
    return rightRotate(node);               // 对节点自身进行右旋操作,返回新的根节点
}

// 右左旋操作函数 RL,和左右旋相反
// 先对节点的右子树进行右旋操作,再对节点自身进行左旋操作
Node* RLrotate(Node* node) {
    node->right = rightRotate(node->right); // 对节点的右子树进行右旋操作
    return leftRotate(node);                // 对节点自身进行左旋操作,返回新的根节点
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
AVL树是一种自平衡二叉搜索树,它的平衡因子(左子树高度减去右子树高度)在任何时候都是-1、0或1。当插入或删除节点后,如果AVL树失去平衡,则需要通过旋转来重新平衡它。 在Python中实现AVL树,可以使用节点类和AVL树类。节点类包括节点值、左子树、右子树、高度和平衡因子等属性。AVL树类包括根节点、插入节点、删除节点、旋转方法和平衡方法等方法。 下面是一个简单的Python实现AVL树代码示例: ```python class Node: def __init__(self, val): self.val = val self.left = None self.right = None self.height = 1 self.balance = 0 class AVLTree: def __init__(self): self.root = None def insert(self, val): self.root = self._insert(self.root, val) def _insert(self, node, val): if not node: return Node(val) if val < node.val: node.left = self._insert(node.left, val) else: node.right = self._insert(node.right, val) node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) node.balance = self.get_balance(node) if node.balance > 1 and val < node.left.val: return self.right_rotate(node) if node.balance < -1 and val > node.right.val: return self.left_rotate(node) if node.balance > 1 and val > node.left.val: node.left = self.left_rotate(node.left) return self.right_rotate(node) if node.balance < -1 and val < node.right.val: node.right = self.right_rotate(node.right) return self.left_rotate(node) return node def delete(self, val): self.root = self._delete(self.root, val) def _delete(self, node, val): if not node: return node if val < node.val: node.left = self._delete(node.left, val) elif val > node.val: node.right = self._delete(node.right, val) else: if not node.left or not node.right: temp = node.left if node.left else node.right if not temp: node = None else: node = temp else: temp = self.get_min(node.right) node.val = temp.val node.right = self._delete(node.right, temp.val) if not node: return node node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) node.balance = self.get_balance(node) if node.balance > 1 and self.get_balance(node.left) >= 0: return self.right_rotate(node) if node.balance < -1 and self.get_balance(node.right) <= 0: return self.left_rotate(node) if node.balance > 1 and self.get_balance(node.left) < 0: node.left = self.left_rotate(node.left) return self.right_rotate(node) if node.balance < -1 and self.get_balance(node.right) > 0: node.right = self.right_rotate(node.right) return self.left_rotate(node) return node def right_rotate(self, node): left_child = node.left node.left = left_child.right left_child.right = node node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) left_child.height = 1 + max(self.get_height(left_child.left), self.get_height(left_child.right)) node.balance = self.get_balance(node) left_child.balance = self.get_balance(left_child) return left_child def left_rotate(self, node): right_child = node.right node.right = right_child.left right_child.left = node node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) right_child.height = 1 + max(self.get_height(right_child.left), self.get_height(right_child.right)) node.balance = self.get_balance(node) right_child.balance = self.get_balance(right_child) return right_child def get_height(self, node): if not node: return 0 return node.height def get_balance(self, node): if not node: return 0 return self.get_height(node.left) - self.get_height(node.right) def get_min(self, node): while node.left: node = node.left return node ``` 这个实现包括插入、删除、旋转和平衡等基本操作。你可以按需调用这些方法,来实现你的具体需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

榆榆欸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值