您的位置:首页 > 新闻 > 资讯 > 网页定做_深圳app网站_生意参谋官网_百度网站收录链接提交

网页定做_深圳app网站_生意参谋官网_百度网站收录链接提交

2024/10/5 17:23:17 来源:https://blog.csdn.net/kirotsupreme/article/details/142628741  浏览:    关键词:网页定做_深圳app网站_生意参谋官网_百度网站收录链接提交
网页定做_深圳app网站_生意参谋官网_百度网站收录链接提交

文章目录

  • 前言
  • 一、单旋
    • (1)左旋
    • (2)右旋
  • 二、双旋
    • (1)左右旋
      • 1.左右旋情况一
      • 2.左右旋情况二
    • (2)右左旋
      • 1.右左旋情况一
      • 2.右左旋情况二
  • 总结


前言

  本章主要介绍AVL树的旋转操作,包括单旋(左旋与右旋)和双旋(左右旋,右左旋)。


一、单旋

(1)左旋

  左旋以下图举例,5的右子树的高度为h+2,左子树高度为h,5的平衡因子为2(右子树高度-左子树的高度),因此需要左旋。左旋操作如下所示:
  2成为5的父亲,5成为2的左子树
  2的左子树放在5的右子树
  5的父亲指向2
注意以下事项:
  判断5是根还是某个子树的根节点
  若5是某个子树的根节点,则要判断5的父亲是右边指向5还是左边指向5
  注意平衡因子的更新

在这里插入图片描述
  下面是AVL树左旋的代码:

		void RotateRL(Node* parent) {Node* subR = parent->right;Node* subRL = subR->left;int bf = subRL->_bf;//在旋转之前获取,旋转之后获取逻辑不对RotateR(parent->right);RotateL(parent);if (bf == 0) {parent->_bf = subR->_bf = subRL->_bf = 0;}else if (bf == 1) {parent->_bf = -1;subR->_bf = subRL->_bf;}else if (bf == -1) {subR->_bf = 1;parent->_bf = subRL->_bf = 0;}else {assert(false);}}

(2)右旋

  右旋以下图举例,5的右子树的高度为h,左子树高度为h+2,5的平衡因子为-2(右子树高度-左子树的高度),因此需要右旋。左旋操作如下所示:
  2成为5的父亲,5成为2的右子树
  2的右子树放在5的左子树
  5的父亲指向2
注意以下事项:
  判断5是根还是某个子树的根节点
  若5是某个子树的根节点,则要判断5的父亲是右边指向5还是左边指向5
在这里插入图片描述
  下面是AVL树右旋的代码:

		void RotateR(Node* parent) {Node* subL = parent->left;Node* subLR = subL->right;Node* parentparent = parent->parent;parent->left=subLR;if(subLR!=nullptr) subLR->parent = parent;subL->right = parent;parent->parent = subL;subL->parent = parentparent;if (parentparent == nullptr) _root = subL;else {if (parentparent->left == parent) parentparent->left = subL;else parentparent->right = subL;}parent->_bf = subL->_bf = 0;}

二、双旋

(1)左右旋

1.左右旋情况一

下图为左右旋的一种情况,具体操作如下:
  将节点2进行左旋
  再将节点5进行右旋

在这里插入图片描述

2.左右旋情况二

  下图为左右旋的另一种情况,这里的操作可简单描述为:将3的左边给2的右边,将3的右边给5的左边,3成为子树根节点,左边指向2,右边指向5,具体操作如下:
  将节点2进行左旋
  再将节点5进行右旋
注意事项:
  在a侧插入和b侧插入新元素时候,各节点的平衡因子变化会有所不用
在这里插入图片描述  下面为左右旋的代码。

		void RotateLR(Node* parent) {Node* subL = parent->left;Node* subLR = subL->right;int bf = subLR->_bf;//在旋转之前获取,旋转之后获取逻辑不对RotateL(parent->left);RotateR(parent);if (bf == 0) {parent->_bf = subL->_bf = subLR->_bf = 0;}else if (bf == 1) {subL->_bf = -1;parent->_bf = subLR->_bf = 0;}else if (bf == -1) {parent->_bf = 1;subL->_bf = subLR->_bf=0;}else {assert(false);}}

(2)右左旋

1.右左旋情况一

下图为左右旋的一种情况,具体操作如下:
  将节点10进行左旋
  再将节点5进行右旋
在这里插入图片描述

2.右左旋情况二

下图为左右旋的另一种情况,这里的操作可简单描述为:将4的左边给3的右边,将4的右边给7的左边,4成为子树根节点,左边指向3,右边指向7,具体操作如下:
  将节点7进行右旋
  再将节点3进行左旋
注意事项:
  在a侧插入和b侧插入新元素时候,各节点的平衡因子变化会有所不用
在这里插入图片描述
  下面为右左旋的代码。

		void RotateRL(Node* parent) {Node* subR = parent->right;Node* subRL = subR->left;int bf = subRL->_bf;//在旋转之前获取,旋转之后获取逻辑不对RotateR(parent->right);RotateL(parent);if (bf == 0) {parent->_bf = subR->_bf = subRL->_bf = 0;}else if (bf == 1) {parent->_bf = -1;subR->_bf = subRL->_bf;}else if (bf == -1) {subR->_bf = 1;parent->_bf = subRL->_bf = 0;}else {assert(false);}}

总结

  本文主要讲用图例和代码呈现的方式详细列举了AVL树旋转的各种情况,希望对各位读者有所帮助。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com