数据结构——AVL树

1.树是什么?

树是一种数据结构,它是由n(n≥1)个有限节点组成一个具有层次关系的集合。
它具有以下的特点:
1. 每个节点有零个或多个子节点;
2. 没有父节点的节点称为根节点;
3. 每一个非根节点有且只有一个父节点;
4. 除了根节点外,每个子节点可以分为多个不相交的子树。

2.AVL树是什么?

AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
它具有以下的特点:
1. 首先是一棵二叉搜索树;
2. 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。

3.示例

简单实现

template <class T>
class AVLTree {
 private:
  class AVLNode {
   private:
    friend class AVLTree;
    int key;
    T data;
    AVLNode *left;
    AVLNode *right;
    // 高度
    int height;

   public:
    AVLNode(int key, T data)
        : key(key), data(data), left(0), right(0), height(1) {
      ;
    }
    ~AVLNode() { ; }
  };

  //根节点
  AVLNode *root;
  // 节点数
  int size;

  void DelNode(AVLNode *node) {
    if (node != NULL) {
      DelNode(node->left);
      DelNode(node->right);
      delete node;
    }
  }

  int getSize() { return size; }

  // 得到当前节点的高度
  int getHeight(AVLNode *node) {
    if (node == NULL) return 0;
    return node->height;
  }

  // 得到当前节点的平衡因子
  int getBalanceFactor(AVLNode *node) {
    if (node == NULL) return 0;
    return getHeight(node->left) - getHeight(node->right);
  }

  bool isBalance(AVLNode *node) {
    if (node == NULL) return true;
    if (ABS(getBalanceFactor(node)) > 1) return false;
    return isBalance(node->left) && isBalance(node->right);
  }

  AVLNode *LL(AVLNode *node)  // 右旋
  {
    AVLNode *_new = node->left;
    node->left = _new->right;
    _new->right = node;
    node->height = MAX(getHeight(node->left), getHeight(node->right)) + 1;
    _new->height = MAX(getHeight(_new->left), getHeight(_new->right)) + 1;
    return _new;
  }

  AVLNode *RR(AVLNode *node)  // 左旋
  {
    AVLNode *_new = node->right;
    node->right = _new->left;
    _new->left = node;
    node->height = MAX(getHeight(node->left), getHeight(node->right)) + 1;
    _new->height = MAX(getHeight(_new->left), getHeight(_new->right)) + 1;
    return _new;
  }

  AVLNode *rebalance(AVLNode *_new) {
    int balance = 0;

    // 插入节点后平衡左右子树
    _new->height = MAX(getHeight(_new->left), getHeight(_new->right)) + 1;
    balance = getBalanceFactor(_new);

    /*
     *  O表示当前节点; L表示左子树; R表示右子树; 下同
     *           O0                    L1
     *       L1      R1            L2      O0
     *     L2  R2          =>    L3      R2  R1
     *   L3
     */
    if (balance > 1 && getBalanceFactor(_new->left) >= 0) {  // 左左
      return LL(_new);
    }

    /*
     *         O0                    O0                     R2
     *     L1      R1            R2      R1             L1      O0
     *   L2  R2          =>    L1  R3           =>    L2      R3  R1
     *        R3              L2
     */
    if (balance > 1 && getBalanceFactor(_new->left) < 0) {  // 左右
      _new->left = RR(_new->left);  // 将左节点左旋,转换为左左状态
      return LL(_new);
    }

    /*
     *         O0                    R1
     *     L1      R1            O0      R2
     *           L2  R2   =>   L1  L2      R3
     *                R3
     */
    if (balance < -1 && getBalanceFactor(_new->right) <= 0)  // 右右
    {
      return RR(_new);
    }

    /*
     *         O0                    O0                     L2
     *     L1      R1            L1      L2             O0      R1
     *           L2  R2   =>           R3  R1    =>   L1  R3      R2
     *          R3                          R2
     */
    if (balance < -1 && getBalanceFactor(_new->right) > 0) {  // 右左
      _new->right = LL(_new->right);  // 将右节点右旋,转换为右右状态
      return RR(_new);
    }

    return _new;
  }

  AVLNode *add(AVLNode *node, int key, T data) {
    if (node == NULL) {
      size++;  // 找到空节点,插入元素
      return new AVLNode(key, data);
    }
    if (key < node->key)  // 插入左子树
      node->left = add(node->left, key, data);
    else if (key > node->key)  // 插入右子树
      node->right = add(node->right, key, data);
    else  // 相同节点,直接返回
      return node;

    return rebalance(node);
  }

  AVLNode *get(AVLNode *node, int key) {
    if (node == NULL) return NULL;
    if (key < node->key)
      return get(node->left, key);
    else if (key > node->key)
      return get(node->right, key);
    else
      return node;
  }
  // 寻找当前树中的最大值
  AVLNode *Max(AVLNode *node) {
    while (node->right != NULL) {
      node = node->right;
    }
    return node;
  }

  AVLNode *remove(AVLNode *node, int key) {
    if (node == NULL) return NULL;

    AVLNode *_new = NULL;  // 删除节点的后继节点
    if (key < node->key) {
      node->left = remove(node->left, key);
      _new = node;
    } else if (key > node->key) {
      node->right = remove(node->right, key);
      _new = node;
    } else {
      if (node->left == NULL) {  // 没有左节点
        _new = node->right;
        size--;
      } else if (node->right == NULL) {  // 没有右节点
        _new = node->left;
        size--;
      } else {  // 存在左右节点,寻找前驱节点替换删除节点
        _new = Max(node->left);
        _new->left = remove(node->left, _new->key);  // 将前驱节点移除
        _new->right = node->right;
      }
    }

    if (_new == NULL) return NULL;  // 删除节点不存在后继节点

    return rebalance(_new);
  }

 public:
  AVLTree() {
    size = 0;
    root = NULL;
  }

  ~AVLTree() { DelNode(root); };

  boolean isEmpty() {
    if (size == 0)
      return TRUE;
    else
      return FALSE;
  }
  // 验证平衡树
  bool isBalance() { return isBalance(root); }

  void add(int key, T data) {
    AVLNode *node = get(root, key);
    if (node != NULL) return;
    root = add(root, key, data);
  }

  T get(int key) {
    AVLNode *node = get(root, key);
    if (node != NULL) return node->data;
    return NULL;
  }

  T remove(int key) {
    AVLNode *node = get(root, key);
    if (node == NULL) return NULL;
    T val = node->data;
    root = remove(root, key);
    delete node;
    return val;
  }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值