AVL(平衡)树的旋转

  在二叉搜索树中,可能会存在几种特别的情况,即左单支、右单支之类的情况,这样的情况在二叉搜索树中查询某个节点代表的内容时,依旧会达到O(N)的时间复杂度,而不能按预期达到O(lgN)的时间复杂度。
  所以在树中旋转树的结构,将树调整为一个满足条件的树–AVLTree(平衡树),即右子树的高度减去左子树的高度的绝对值小于2。为了达到AVL树,有四种基本情况,所以对应四种旋转方式,左单旋,右单旋,右左双旋,左右双旋。
  ——-插入40——-
  -------插入40-------
  ——-插入25——-
  -------插入25-------

需注意:双旋中各分两种情况,每种情况的分法按照插入节点的双亲节点插入后的平衡因子为1或是-1判断插入的是左孩子还是右孩子,并在双旋之后对平衡因子再次更新

  ——-插入17——-

-------插入17-------
  ——-插入12——-
-------插入12-------
  ——-插入37——-
-------插入37-------
  ——-插入32——-
-------插入32-------
  选则所需条件和旋转方式均在图中标注。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AVL平衡树是一种自平衡二叉查找,主要解决二叉查找在插入和删除操作时可能会失去平衡的问题。在AVL平衡树中,每个节点都有一个平衡因子,即左子的高度减去右子的高度,平衡因子的值只能为-1、0、1三种。当插入或删除一个节点后,如果导致某个节点的平衡因子的绝对值大于1,就需要通过旋转操作来重新平衡这个节点及其子。 下面是一个非指针实现的AVL平衡树的示例代码: ```c++ #include <iostream> using namespace std; const int MAXN = 100; class AVLTree { public: AVLTree() : size(0) {} bool insert(int val) { if (size == MAXN) return false; root = insert(root, val); size++; return true; } bool remove(int val) { if (size == 0) return false; root = remove(root, val); size--; return true; } void print() { inorder(root); } private: struct Node { int val, h; Node *l, *r; Node(int v, Node *L = NULL, Node *R = NULL) : val(v), h(0), l(L), r(R) {} int height() { return this ? h : -1; } int balance() { return r->height() - l->height(); } void update() { h = max(l->height(), r->height()) + 1; } Node *rotate_left() { Node *p = r; r = p->l; p->l = this; update(); p->update(); return p; } Node *rotate_right() { Node *p = l; l = p->r; p->r = this; update(); p->update(); return p; } Node *rotate_left_right() { r = r->rotate_right(); return rotate_left(); } Node *rotate_right_left() { l = l->rotate_left(); return rotate_right(); } }; Node *root; int size; Node *insert(Node *p, int val) { if (!p) return new Node(val); if (val < p->val) { p->l = insert(p->l, val); if (p->balance() == 2) { if (val < p->r->val) p = p->rotate_right_left(); else p = p->rotate_left(); } } else if (val > p->val) { p->r = insert(p->r, val); if (p->balance() == -2) { if (val > p->l->val) p = p->rotate_left_right(); else p = p->rotate_right(); } } p->update(); return p; } Node *remove(Node *p, int val) { if (!p) return NULL; if (val < p->val) { p->l = remove(p->l, val); if (p->balance() == -2) { if (p->l->balance() <= 0) p = p->rotate_right(); else p = p->rotate_left_right(); } } else if (val > p->val) { p->r = remove(p->r, val); if (p->balance() == 2) { if (p->r->balance() >= 0) p = p->rotate_left(); else p = p->rotate_right_left(); } } else { if (!p->l && !p->r) { delete p; return NULL; } else if (p->l) { Node *q = p->l; while (q->r) q = q->r; p->val = q->val; p->l = remove(p->l, q->val); if (p->balance() == -2) { if (p->l->balance() <= 0) p = p->rotate_right(); else p = p->rotate_left_right(); } } else { Node *q = p->r; while (q->l) q = q->l; p->val = q->val; p->r = remove(p->r, q->val); if (p->balance() == 2) { if (p->r->balance() >= 0) p = p->rotate_left(); else p = p->rotate_right_left(); } } } p->update(); return p; } void inorder(Node *p) { if (!p) return; inorder(p->l); cout << p->val << " "; inorder(p->r); } }; ``` 这里实现了AVL平衡树的插入、删除和中序遍历操作。其中,AVL平衡树旋转操作被封装在了节点结构体中,包括左旋、右旋、左右旋和右左旋四种情况。具体实现时,需要注意节点的高度、平衡因子的计算和更新,以及对的递归遍历等细节问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值