农业 网站源码制作apk的软件
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:14
当前位置: 首页 > news >正文
农业 网站源码,制作apk的软件,昆明网站建设公司猫咪科技,重庆专业网站建设文章目录 AVL树旋转单旋右单旋左单旋 双旋左右双旋右左双旋 平衡因子的更新左右双旋右左双旋 判断是不是AVL树时间复杂度分析全部的代码 AVL树
旋转
单旋
单旋是纯粹的一边高 单旋平衡因子是同号
右单旋
a,b,c自身不能发生旋转 并且也不能不向上继续更新#xff08;不能停… 文章目录 AVL树旋转单旋右单旋左单旋 双旋左右双旋右左双旋 平衡因子的更新左右双旋右左双旋 判断是不是AVL树时间复杂度分析全部的代码 AVL树
旋转
单旋
单旋是纯粹的一边高 单旋平衡因子是同号
右单旋
a,b,c自身不能发生旋转 并且也不能不向上继续更新不能停止更新 插入之前是h2插入后进行旋转后是h2没有对pParent它的子树的高度产生影响不用继续向上更新
// 链接孩子和父亲
// 右单旋,旋转点是parent
void Rotate(Node* parent)
{Node* subL parent-_left;Node* subLR subL-_right;parent-_left subLR;// b可能为空树if (suLR ! nullptr)subLR-_parent parent;// 记录parent的parentpParent parent-_parent;subL-_right parent;parent-_parent subL;// 1. 10是这棵树的总根if (parent _root){subL _root;subL-_parent nullptr;}else{// 2. 10是这棵树的局部根// 就有父亲的父亲节点// pParent左可能是parent,右也可能是parentif (pParent-_left parent){pParent-_left subL;}else{pParent-_right subL;}subL-_parent pParent;}// 更新平衡因子subL-_bf 0;parent-_bf 0;}左单旋
左单旋和右单旋类似
// 左单旋,旋转点是parent
void RotateL(Node* parent)
{Node* subR parent-_right;Node* subRL subR-_left;parent-_right subRL;// b不是空树if (subRL)subRL-_parent parent;// 记录父亲节点的父亲节点Node* pParent parent-_parent;subR-_left parent;parent-_parent subR;// 1. 10是这棵树的总根if (_root parent){_root subR;subR-_parent nullptr;}else{// 2. 10是这棵树的局部根if (pParent-_left parent){pParent-_left subR;}else{pParent-_right subR;}subR-_parent pParent;}subR-_bf 0;parent-_bf 0;
}双旋
双旋平衡因子会异号 双旋是进行两次单旋
对于5来说右边高对于10来说左边高需要进行双旋 下面是进行的单旋解决不了问题 对于5来说右边高对于10来说左边高需要进行双旋 进行单旋解决不了问题会变成下面的样子
左右双旋
h 0
h 1
右左双旋
右左双旋和左右双旋类似这里就不画了
平衡因子的更新
左右双旋
双旋和单旋的平衡因子更新方式不同双旋按照单旋的方式更新后5,108都是0不符合逻辑
左右双旋中h0和h1具体场景分析下面我们将a/b/c子树抽象为高度h的AVL 子树进行分析另外我们需要把b子树的细节进一步展开为8和左子树高度为h-1的e和f子树因为 我们要对b的父亲5为旋转点进行左单旋左单旋需要动b树中的左子树。b子树中新增结点的位置 不同平衡因子更新的细节也不同通过观察8的平衡因子不同这里我们要分三个场景讨论。
场景1h 1时新增结点插入在e子树e子树高度从h-1并为h并不断更新8-5-10平衡因子 引发旋转其中8的平衡因子为-1旋转后8和5平衡因子为010平衡因子为1。场景2h 1时新增结点插入在f子树f子树高度从h-1变为h并不断更新8-5-10平衡因子引 发旋转其中8的平衡因子为1旋转后8和10平衡因子为05平衡因子为-1。场景3h 0时a/b/c都是空树b自己就是一个新增结点不断更新5-10平衡因子引发旋转其中8的平衡因子为0旋转后8和10和5平衡因子均为0。 8的平衡因子会影响其它的平衡因子
插入到8的左边8的平衡因子为-1插入到8的右边8的平衡因子为18本身就是要插入的节点8的平衡因子为0
// 左右双旋
void RotateLR(Node* parent)
{Node* subL parent-_left;Node* subLR subL-_right;// 提前存平衡因子int bf subLR-_bf;RotateL(parent-_left);RotateR(parent);if (subLR-_bf -1){subLR-_bf 0;subL-_bf 0;parent-_bf 1;}else if (subLR-_bf 1){subLR-_bf 0;subL-_bf -1;parent-_bf 0;}else if (subLR-_bf 0){subLR-_bf 0;subL-_bf 0;parent-_bf 0;}else{assert(false);}
}右左双旋
跟左右双旋类似下面我们将a/b/c子树抽象为高度h的AVL子树进行分析另外我们需要把b子树的细节进一步展开为12和左子树高度为h-1的e和f子树因为我们要对b的父亲15为旋转点进行右单旋右单旋需要动b树中的右子树。b子树中新增结点的位置不同平衡因子更新的细节也不同通过观察12的平衡因子不同这里我们要分三个场景讨论。
场景1h 1时新增结点插入在e子树e子树高度从h-1变为h并不断更新12-15-10平衡因子引发旋转其中12的平衡因子为-1旋转后10和12平衡因子为015平衡因子为1。场景2h 1时新增结点插入在f子树f子树高度从h-1变为h并不断更新12-15-10平衡因子引发旋转其中12的平衡因子为1旋转后15和12平衡因子为010平衡因子为-1。场景3h 0时a/b/c都是空树b自己就是一个新增结点不断更新15-10平衡因子引发旋转其中12的平衡因子为0旋转后10和12和15平衡因子均为0。 3种情况
插入到e那边插入到f那边b本身就是插入的点
// 右左双旋
void RotateRL(Node* parent)
{Node* subR parent-_right;Node* subRL subR-_left;// 提前存放平衡因子int bf subRL-_bf;RotateR(parent-_right);RotateL(parent);if (bf -1){subRL-_bf 0;parent-_bf 0;subR-_bf 1;}else if (bf 1){subRL-_bf 0;parent-_bf -1;subR-_bf 0;}else if (bf 0){subRL-_bf 0;parent-_bf 0;subR-_bf 0;}else{assert(false);}
}判断是不是AVL树
用高度差的绝对值是否 1来检查
// 算树的高度,左右子树高的那个加1
int _Height(Node* root)
{if (root nullptr){return 0;}int leftHeight _Height(root-_left);int rightHeight _Height(root-_right);return leftHeight rightHeight ? leftHeight 1 : rightHeight 1;
}// 判断是不是AVL树
bool _IsBalanceTree(Node* root)
{// 空树也是AVL树if (root nullptr)return true;// pRoot的子树的平衡因子,左右子树的高度差int _leftheight _Height(root-_left);int _rightheight _Height(root-_right);int diff _rightheight - _leftheight;// 高度差超过2或者pRoot的平衡因子不等于计算出的平衡因子就不是AVL树if (abs(diff) 2){cout root-_kv.first 高度差异常 endl;return false;}else if (diff ! root-_bf){cout root-_kv.first 平衡因子异常 endl;return false;}// pRoot节点的左树和右树都是AVL树,那么就是AVL树return _IsBalanceTree(root-_left) _IsBalanceTree(root-_right);
}时间复杂度分析
插入logN,寻找插入的位置会找到叶子的位置 旋转常数次 调整假设最坏情况调整到根logN平衡因子为-1⁄1,要继续调整 时间复杂度logN
全部的代码
#pragma once
#includeiostream
#includeassert.husing namespace std;templateclass K, class V
struct AVLTreeNode
{// 需要parent指针pairK, V _kv;AVLTreeNodeK, V* _left;AVLTreeNodeK, V* _right;AVLTreeNodeK, V* _parent;int _bf;// 平衡因子AVLTreeNode(const pairK, V kv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr),_bf(0)// 刚插入的节点平衡因子都是0{}
};templateclass K, class V
class AVLTree
{typedef AVLTreeNodeK, V Node;
public:bool insert(const pairK, V kv){if (_root nullptr){_root new Node(kv);return true;}Node* parent nullptr;Node* cur _root;while (cur){if (cur-_kv.first kv.first){parent cur;cur cur-_right;}else if (cur-_kv.first kv.first){parent cur;cur cur-_left;}else{// 不冗余return false;}}// 链接父节点cur new Node(kv);if (parent-_kv.first kv.first){parent-_right cur;}else{parent-_left cur;}cur-_parent parent;// 更新平衡因子// 控制平衡while (parent){if (parent-_left cur)parent-_bf–;else // if (parent-_right cur)parent-_bf;if (parent-_bf 0){break;}else if (parent-_bf -1 || parent-_bf 1){cur parent;parent parent-_parent;}else if (parent-_bf 2 || parent-_bf -2){// 旋转if (parent-_bf -2 cur-_bf -1){// 右旋,左高右低RotateR(parent);}else if(parent-_bf 2cur-_bf 1){// 左旋,右高左低RotateL(parent);}else if(parent-_bf -2cur-_bf 1){// 左右双旋,右高左高RotateLR(parent);}else if (parent-_bf 2 cur-_bf -1){// 右左双旋,左高右高RotateRL(parent);}else{assert(false);}break;}else{// 逻辑错误,之前就不是AVL树assert(false);}}return true;}// 右单旋,旋转点是parentvoid RotateR(Node* parent){Node* subL parent-_left;Node* subLR subL-_right;parent-_left subLR;// b可能为空树if (subLR ! nullptr)subLR-_parent parent;// 记录parent的parentNode* pParent parent-_parent;subL-_right parent;parent-_parent subL;// 1. 10是这棵树的总根if (parent _root){_root subL;subL-_parent nullptr;}else{// 2. 10是这棵树的局部根// pParent左可能是parent,右也可能是parentif (pParent-_left parent){pParent-_left subL;}else{pParent-_right subL;}subL-_parent pParent;}// 更新平衡因子subL-_bf 0;parent-_bf 0;}// 左单旋,旋转点是parentvoid RotateL(Node* parent){Node* subR parent-_right;Node* subRL subR-_left;parent-_right subRL;// b不是空树if (subRL)subRL-_parent parent;// 记录父亲节点的父亲节点Node* pParent parent-_parent;subR-_left parent;parent-_parent subR;// 1. 10是这棵树的总根if (_root parent){_root subR;subR-_parent nullptr;}else{// 2. 10是这棵树的局部根if (pParent-_left parent){pParent-_left subR;}else{pParent-_right subR;}subR-_parent pParent;}subR-_bf 0;parent-_bf 0;}// 左右双旋void RotateLR(Node* parent){Node* subL parent-_left;Node* subLR subL-_right;// 提前存平衡因子int bf subLR-_bf;RotateL(parent-_left);RotateR(parent);if (subLR-_bf -1){subLR-_bf 0;subL-_bf 0;parent-_bf 1;}else if (subLR-_bf 1){subLR-_bf 0;subL-_bf -1;parent-_bf 0;}else if (subLR-_bf 0){subLR-_bf 0;subL-_bf 0;parent-_bf 0;}else{assert(false);}}// 右左双旋void RotateRL(Node* parent){Node* subR parent-_right;Node* subRL subR-_left;// 提前存放平衡因子int bf subRL-_bf;RotateR(parent-_right);RotateL(parent);if (bf -1){subRL-_bf 0;parent-_bf 0;subR-_bf 1;}else if (bf 1){subRL-_bf 0;parent-_bf -1;subR-_bf 0;}else if (bf 0){subRL-_bf 0;parent-_bf 0;subR-_bf 0;}else{assert(false);}}Node* Find(const K key){Node* cur _root;while (cur){if (cur-_kv.first key){cur cur-_right;}else if (cur-_kv.first key){cur cur-_left;}else{return cur;}}return nullptr;}// 大小int Size(){return _Size(_root);}// 判断是不是AVL树bool IsBalanceTree(){return _IsBalanceTree(_root);}// 算树的高度int Height(){_Height(_root);}// 中序void InOrder(){_InOrder(_root);cout endl;}
private:// 算树的高度,左右子树高的那个加1int _Height(Node* root){if (root nullptr){return 0;}int leftHeight _Height(root-_left);int rightHeight _Height(root-_right);return leftHeight rightHeight ? leftHeight 1 : rightHeight 1;}// 算树的节点个数 int _Size(Node* root){if (root nullptr)return 0;return _Size(root-_left) _Size(root-_right) 1;}// 判断是不是AVL树bool _IsBalanceTree(Node* root){// 空树也是AVL树if (root nullptr)return true;// pRoot的子树的平衡因子,左右子树的高度差int _leftheight _Height(root-_left);int _rightheight _Height(root-_right);int diff _rightheight - _leftheight;// 高度差超过2或者pRoot的平衡因子不等于计算出的平衡因子就不是AVL树if (abs(diff) 2){cout root-_kv.first 高度差异常 endl;return false;}else if (diff ! root-_bf){cout root-_kv.first 平衡因子异常 endl;return false;}// pRoot节点的左树和右树都是AVL树,那么就是AVL树return _IsBalanceTree(root-_left) _IsBalanceTree(root-_right);}void _InOrder(Node* root){if (root nullptr){return;}_InOrder(root-_left);cout root-_kv.first : root-_kv.second endl;_InOrder(root-_right);}private:Node* _root nullptr;
};#includeAVLTree.hvoid TestAVLTree1()
{AVLTreeint, int t;// 常规的测试⽤例int a[] { 16, 3, 7, 11, 9, 26, 18, 14, 15 };// 特殊的带有双旋场景的测试⽤例//int a[] { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };for (auto e : a){t.insert({ e, e });}t.InOrder();cout t.IsBalanceTree() endl;
}int main()
{TestAVLTree1();return 0;
}
- 上一篇: 农林牧渔行业网站建设软件技术培训
- 下一篇: 农业机械网站模板竞价广告代运营
相关文章
-
农林牧渔行业网站建设软件技术培训
农林牧渔行业网站建设软件技术培训
- 技术栈
- 2026年03月21日
-
农村网站建设必要性辣条类网站建设规划书
农村网站建设必要性辣条类网站建设规划书
- 技术栈
- 2026年03月21日
-
农场理财网站建设环球贸易网app
农场理财网站建设环球贸易网app
- 技术栈
- 2026年03月21日
-
农业机械网站模板竞价广告代运营
农业机械网站模板竞价广告代运营
- 技术栈
- 2026年03月21日
-
农业建设公司网站jsp网站建立
农业建设公司网站jsp网站建立
- 技术栈
- 2026年03月21日
-
农业建设项目管理信息系统网站动漫设计师
农业建设项目管理信息系统网站动漫设计师
- 技术栈
- 2026年03月21日






