AVL树——左单旋、右单旋、左右双旋、右左双旋

2024-01-04 18:10
文章标签 avl 左右双 单旋 双旋

本文主要是介绍AVL树——左单旋、右单旋、左右双旋、右左双旋,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本篇文章主要介绍AVL树的四种旋转方法。

首先,右单旋:

插入节点位于根节点的左子节点的左子树。


void _RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;Node* pparent = parent->_parent;subL->_parent = pparent;parent->_parent = subL;if (pparent == NULL)_root = subL;else{if (parent = pparent->_left)pparent->_left = subL;elsepparent->_right = subL;}parent->_bf = subL->_bf = 0;}

左单旋:

插入节点位于根节点的右子节点的右子树。


void  _RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;//处理节点parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;Node* pparent = parent->_parent;subR->_parent = pparent;parent->_parent = subR;if (parent == _root)_root = subR;else{if (pparent->_left == parent)pparent->_left = subR;elsepparent->_right = subR;}parent->_bf = subR->_bf = 0;}

左右双旋:

插入节点位于根节点的左子节点的右子树。


void _RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;_RotateL(subL);_RotateR(parent);if (bf == 1)subL->_bf = -1;if (bf == -1)parent->_bf = 1;}

右左双旋:

插入节点位于根节点的右子节点的左子树。


void _RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;_RotateR(subR);_RotateL(parent);if (bf == 1)parent->_bf = -1;else if (bf == -1)subR->_bf = 1;}

接下来是AVL树的代码:

#pragma once
#include<iostream>
using namespace std;template <class K,class V>
struct AVLTreeNode
{AVLTreeNode(const K& key,const V& value):_left(NULL), _right(NULL),_parent(NULL), _key(key), _value(value), _bf(0){}AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;K _key;V _value;int _bf;
};template<class K,class V>
class AVLTree
{typedef AVLTreeNode<K, V> Node;public:AVLTree():_root(NULL){}bool Insert(const K& key,const  V& value){if (_root == NULL){_root = new Node(key, value);return true;}//找插入位置Node* cur = _root;Node* parent = NULL;while (cur){if (key < cur->_key){parent = cur;cur = cur->_left;}else if (key > cur->_key){parent = cur;cur = cur->_right;}elsereturn false;}//插入cur = new Node(key, value);if (key < parent->_key)parent->_left = cur;elseparent->_right = cur;cur->_parent = parent;//更新双亲的平衡因子while (parent){if (parent->_left == cur)parent->_bf--;elseparent->_bf++;if (parent->_bf == 0)break;else if (parent->_bf == 1 || parent->_bf == -1){cur = parent;parent = cur->_parent;}else{if (parent->_bf == 2){if (cur->_bf == 1)_RotateL(parent);else_RotateRL(parent);}else{if (cur->_bf == -1)_RotateR(parent);else_RotateLR(parent);}break;}}return true;}void InOreder(){return _InOrder(_root);}bool IsBalance(){return _IsBalance(_root);}private:bool _IsBalance(Node* root){if (_root == NULL)return true;int LeftHight = _Hight(_root->_left);int RightHight = _Hight(_root->_right);if (abs(LeftHight - RightHight) >= 2)return false;return _IsBalance(_root->_left) && _IsBalance(_root->_right);}  int _Hight(Node* _root){if (_root == NULL)return 0;int LeftHight = _Hight(_root->_left)+1;int RightHight = _Hight(_root->_right)+1;return LeftHight > RightHight ? LeftHight+1 : RightHight+1;}void  _RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;//处理节点parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;Node* pparent = parent->_parent;subR->_parent = pparent;parent->_parent = subR;if (parent == _root)_root = subR;else{if (pparent->_left == parent)pparent->_left = subR;elsepparent->_right = subR;}parent->_bf = subR->_bf = 0;}void _RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;Node* pparent = parent->_parent;subL->_parent = pparent;parent->_parent = subL;if (pparent == NULL)_root = subL;else{if (parent = pparent->_left)pparent->_left = subL;elsepparent->_right = subL;}parent->_bf = subL->_bf = 0;}void _RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;_RotateR(subR);_RotateL(parent);if (bf == 1)parent->_bf = -1;else if (bf == -1)subR->_bf = 1;}void _RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;_RotateL(subL);_RotateR(parent);if (bf == 1)subL->_bf = -1;if (bf == -1)parent->_bf = 1;}void _InOrder(Node* _root){if (_root){_InOrder(_root->_left);cout << " " << _root->_key << " " << _root->_value << endl;_InOrder(_root->_right);}}private:Node* _root;};void TestAVLTree()
{int array[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };AVLTree<int, int> t;for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++){t.Insert(i, array[i]);}t.InOreder();if (t.IsBalance())cout << "平衡" << endl;elsecout << "不平衡" << endl;}

这篇关于AVL树——左单旋、右单旋、左右双旋、右左双旋的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/570156

相关文章

AVL 树的旋转

什么是 AVL 树? AVL 树是一种自平衡二叉搜索树(Binary Search Tree, BST),以其发明者 G. M. Adelson-Velsky 和 E. M. Landis 的名字命名。它的特点是对于任意一个节点,其左右子树的高度差(平衡因子)不超过 1,这确保了 AVL 树的高度在 O(log n) 的范围内,从而保证了插入、删除和查找操作的时间复杂度都是 O(log n)。

【C++】【数据结构】一步一步写平衡二叉树[AVL]

转载:有修正,原作者存在一些错误,这里进行了更正。/* 平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体第一个引入平衡概念的二叉树。特点:对于每一个结点,它的左右子树的高度之差不能超过1,若插入或删除一个节点之后使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态。这个方案很好的解决的了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度

以人口金字塔图为例,在线绘制左右双侧堆叠条形图

导读: 人口金字塔(population pyramids)用于展示一个特定人口的年龄和性别分布。本质上是一种水平条形图。左侧是男性的数据,右侧是女性的数据。 Proc Natl Acad Sci U S A.文章《Demographic change and assimilation in the early 21st-century United States》fig 1的人口金字

C++深入理解AVL树的设计与实现:旋转操作详解

C++深入理解AVL树的设计与实现:旋转操作详解 AVL树(Adelson-Velsky and Landis Tree)是一种自平衡二叉搜索树,通过在插入和删除节点时进行旋转操作来保持树的平衡。AVL树的每个节点都维护一个平衡因子,即左右子树的高度差,确保其绝对值不超过1。本文将详细介绍如何实现一个AVL树,并提供旋转操作的实现细节。 一、AVL树的基本概念 AVL树是一种高度平衡的二叉搜

AVL树及其性质

概念 AVL树是一种自平衡二叉搜索树,由G.M. Adelson-Velsky和E.M. Landis在1962年提出。AVL树的特点是任何节点的两个子树的高度最多相差1,这个特性保证了树的平衡,从而保证了树的主要操作(如插入、删除和查找)的时间复杂度为O(log n)。 AVL树的主要性质 平衡因子: 每个节点都有一个平衡因子,定义为右子树高度减去左子树高度。在AVL树中,每个节点的平衡

AVL 树的实现与应用

目录 引言AVL 树简介AVL 树的性质AVL 树的旋转 右单旋 (RR)左单旋 (LL)右左双旋 (RL)左右双旋 (LR)AVL 树的实现 AVL 树节点AVL 树类 插入删除旋转验证代码示例性能考量总结参考文献 引言 在计算机科学中,AVL 树是一种自平衡的二叉搜索树。它由 Adelson-Velsky 和 Landis 在 1962 年提出,以他们的名字首字母命名。AVL 树

为什么AVL fire DVI 界面里面的response Editor project 中的Summary result 点不了???

🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!! 问题描述   为什么AVL fire DVI 界面里面的response Editor project 中的Summary result 点不了??

搜索二叉树进阶之AVL树

前言 二叉搜索树(BST)是一种基础的数据结构,能够高效地进行搜索、插入和删除操作。然而,在最坏的情况下,普通的BST可能会退化成一条链表,导致操作效率降低。为了避免这种情况,出现了自平衡二叉搜索树,AVL树就是其中的一种。 一、什么是AVL树? AVL树是Adelson-Velsky和Landis在1962年发明的一种自平衡二叉搜索树。它的特点是通过对树进行旋转操作来保持平衡,以确保在最坏

【C++】平衡二叉树(AVL树)的实现

目录 一、AVL树的概念二、AVL树的实现1、AVL树的定义2. 平衡二叉树的插入2.1 按照二叉排序树的方式插入并更新平衡因子2.2 AVL树的旋转2.2.1 新节点插入较高左子树的左侧(LL平衡旋转)2.2.2 新节点插入较高右子树的右侧(RR平衡旋转)2.2.3 新节点插入较高左子树的右侧(LR平衡旋转)2.2.4 新节点插入较高右子树的左侧(RL平衡旋转)2.2.5 总结 3 平衡

AVL许可证更新

随着科技的飞速发展,软件已成为企业运营不可或缺的部分。然而,软件许可证的更新和管理成为了企业面临的重要挑战。AVL许可证更新作为企业软件管理的关键环节,正逐渐受到企业的关注。本文将深入探讨AVL许可证更新的重要性、最佳实践以及如何实现高效的许可证管理,帮助企业迈向未来。 一、AVL许可证更新的重要性 适应市场变化:软件行业的发展日新月异,新的技术和产品不断涌现。为了保持竞争力,企业需要跟上市