当前位置: 首页 > news >正文

代做网站推广的公司哪家好百度一下一下你就知道

代做网站推广的公司哪家好,百度一下一下你就知道,斯塔德迈尔球衣,河北中太建设集团有限公司网站文章目录 AVL树AVL树的概念AVL树节点的定义AVL树的插入AVL树的旋转右单旋左单旋左右双旋右左双旋 代码实现 总结 AVL树 AVL树的概念 二叉搜索树在顺序有序或接近有序的情况下,而插入搜索树将退化为单叉树,此时查找的时间复杂度为O(n),效率低…

文章目录

    • AVL树
      • AVL树的概念
      • AVL树节点的定义
      • AVL树的插入
      • AVL树的旋转
        • 右单旋
        • 左单旋
        • 左右双旋
        • 右左双旋
      • 代码实现
    • 总结

AVL树

AVL树的概念

二叉搜索树在顺序有序或接近有序的情况下,而插入搜索树将退化为单叉树,此时查找的时间复杂度为O(n),效率低下。
两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新节点后,保证每个节点的左右子树高度差的绝对值不超过1,即可降低树的高度,减少平均搜索长度。因此,AVL树也被叫做高度平衡二叉搜索树,插入,查找,删除在平均和最坏情况下的时间复杂度都是O( l o g 2 n log_2 n log2n)。

AVL树节点的定义

	template<class K, class V>struct AVLTreeNode{AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;pair<K, V> _kv;int _bf; //balance factor 平衡因子AVLTreeNode(const pair<K, V>& kv):_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_bf(0){}};

注意:实现AVL树平衡因子不是必须的,只不过有了平衡因子帮助我们更便捷地控制整棵树。

AVL树的插入

  1. 根据二叉搜索树的规则插入新节点
bool Insert(const pair<K, V> & kv){root为空,特殊处理if (_root == nullptr){_root = new Node(kv);return true;}Node* curr = _root;Node* parent = nullptr;while (curr){if (curr->_kv.first < kv.first){parent = curr;curr = curr->_right;}else if (curr->_kv.first > kv.first){parent = curr;curr = curr->_left;}else{return false;}}将新节点和其父亲节点链接起来Node* newnode = new Node(kv);if (parent->_kv.first < kv.first)parent->_right = newnode;elseparent->_left = newnode;newnode->_parent = parent;......}
  1. 不断向上更新平衡因子
    1. 当前平衡因子为0,说明插入之前平衡因子为1 / -1,插入之后不改变树的高度,不会影响其他祖先节点,此时更新结束。
    2. 当前平衡因子为1 / -1,说明插入之前平衡因子为0,插入之后当前节点地高度发生变化,会影响其他祖先节点,但是不违反规则,需要向上对祖先节点进行更新,直至当前节点为root。
    3. 当前平衡因子为 2 / -2,此时当前节点所在地子树违反了平衡规则,需要进行处理–>旋转。
while (parent)
{if (parent->_left == newnode){parent->_bf--;}else{parent->_bf++;}if (parent->_bf == 0)break;else if (parent->_bf == -1 || parent->_bf == 1){newnode = parent;parent = parent->_parent;}else if (parent->_bf == -2 || parent->_bf == 2){旋转处理}else{assert(false);}
}

AVL树的旋转

右单旋

在这里插入图片描述

void RotatoR(Node* parent)
{Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;Node* ppnode = parent->_parent;parent->_parent = subL;if (parent == _root){_root = subL;subL->_parent = nullptr;}else{if (ppnode->_left == parent)ppnode->_left = subL;elseppnode->_right = subL;subL->_parent = ppnode;}parent->_bf = 0;subL->_bf = 0;
}
左单旋

在这里插入图片描述

void RotatoL(Node* parent)
{Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;Node* ppnode = parent->_parent;parent->_parent = subR;if (parent == _root){_root = subR;subR->_parent = nullptr;}else{if (ppnode->_left == parent)ppnode->_left = subR;elseppnode->_right = subR;subR->_parent = ppnode;}parent->_bf = 0;subR->_bf = 0;
}
左右双旋

在这里插入图片描述
旋转之前,45的平衡因子可能是-1/0/1,旋转完成之后,根据情况对其他节点的平衡因子进行调整

void RotatoLR(Node* parent)
{Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;RotatoL(subL);RotatoR(parent);subLR->_bf = 0;if (bf == 0){subL->_bf = 0;parent->_bf = 0;}else if (bf == 1){subL->_bf = -1;parent->_bf = 0;}else if (bf == -1){subL->_bf = 0;parent->_bf = 1;}
}
右左双旋

在这里插入图片描述

void RotatoRL(Node* parent)
{Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;subRL->_bf = 0;RotatoR(subR);RotatoL(parent);if (bf == 0){subR->_bf = 0;parent->_bf = 0;}else if (bf == 1){subR->_bf = 0;parent->_bf = -1;}else if (bf == -1){subR->_bf = 1;parent->_bf = 0;}
}

代码实现

namespace xxx
{template<class K, class V>struct AVLTreeNode{AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;pair<K, V> _kv;int _bf; //balance factor 平衡因子AVLTreeNode(const pair<K, V>& kv):_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_bf(0){}};template<class K, class V>class AVLTree{typedef AVLTreeNode<K, V> Node;public:bool Insert(const pair<K, V> & kv){if (_root == nullptr){_root = new Node(kv);return true;}Node* curr = _root;Node* parent = nullptr;while (curr){if (curr->_kv.first < kv.first){parent = curr;curr = curr->_right;}else if (curr->_kv.first > kv.first){parent = curr;curr = curr->_left;}else{return false;}}Node* newnode = new Node(kv);if (parent->_kv.first < kv.first)parent->_right = newnode;elseparent->_left = newnode;newnode->_parent = parent;while (parent){if (parent->_left == newnode){parent->_bf--;}else{parent->_bf++;}if (parent->_bf == 0)break;else if (parent->_bf == -1 || parent->_bf == 1){newnode = parent;parent = parent->_parent;}else if (parent->_bf == -2 || parent->_bf == 2){if (parent->_bf == 2 && newnode->_bf == 1){RotatoL(parent);}else if (parent->_bf == -2 && newnode->_bf == -1){RotatoR(parent);}else if (parent->_bf == -2 && newnode->_bf == 1){RotatoLR(parent);}else if (parent->_bf == 2 && newnode->_bf == -1){RotatoRL(parent);}else{assert(false);}break;}else{assert(false);}}return true;}void RotatoL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;Node* ppnode = parent->_parent;parent->_parent = subR;if (parent == _root){_root = subR;subR->_parent = nullptr;}else{if (ppnode->_left == parent)ppnode->_left = subR;elseppnode->_right = subR;subR->_parent = ppnode;}parent->_bf = 0;subR->_bf = 0;}void RotatoR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;Node* ppnode = parent->_parent;parent->_parent = subL;if (parent == _root){_root = subL;subL->_parent = nullptr;}else{if (ppnode->_left == parent)ppnode->_left = subL;elseppnode->_right = subL;subL->_parent = ppnode;}parent->_bf = 0;subL->_bf = 0;}void RotatoLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;RotatoL(subL);RotatoR(parent);subLR->_bf = 0;if (bf == 0){subL->_bf = 0;parent->_bf = 0;}else if (bf == 1){subL->_bf = -1;parent->_bf = 0;}else if (bf == -1){subL->_bf = 0;parent->_bf = 1;}}void RotatoRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;subRL->_bf = 0;RotatoR(subR);RotatoL(parent);if (bf == 0){subR->_bf = 0;parent->_bf = 0;}else if (bf == 1){subR->_bf = 0;parent->_bf = -1;}else if (bf == -1){subR->_bf = 1;parent->_bf = 0;}}void InOrder(){_InOrder(_root);cout << endl;}bool IsAVLTree(){return _IsAVLTree(_root);}private:bool _IsAVLTree(Node* root){if (root == nullptr)return true;int leftH = Height(root->_left);int rightH = Height(root->_right);return abs(leftH - rightH) <= 1&& _IsAVLTree(root->_left)&& _IsAVLTree(root->_right);}int Height(Node* node){if (node == nullptr)return 0;int leftH = Height(node->_left);int rightH = Height(node->_right);return 1 + max(leftH, rightH);}void _InOrder(Node* root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_kv.second << ' ';_InOrder(root->_right);}Node* _root = nullptr;};
}

总结

AVL树是一棵绝对平衡的二叉搜索树,其要求每个节点的左右子树高度差的绝对值都不超过1,这样可以保证查询时高效的时间复杂度,即 l o g 2 ( N ) log_2 (N) log2(N)。但是如果要对AVL树做一些结构修改的操作,性能非常低下,比如:插入时要维护其绝对平衡,旋转的次数比较多。因此:如果需要一种查询高效且有序的数据结构,而且数据的个数为静态的(即不会改变),可以考虑AVL树,但一个结构经常修改,就不太适合。

http://www.yidumall.com/news/62516.html

相关文章:

  • 从百万到千万 网站怎么优化网络广告文案案例
  • 成都网站建设-中国互联培训学校资质办理条件
  • 西丽做网站广告图片
  • 免费h5网站模版app推广
  • 汉阳网站建设苏州关键词排名提升
  • 微网站建设哪家好平面设计
  • 餐饮服务案例100例seol英文啥意思
  • 电脑怎么做网站服务器苏州百度推广代理商
  • 网站源码 正在建设中上海seo优化服务公司
  • 国外网站做acm题目比较好关键词排名查询
  • 广州开发区建设和环境保护局网站怎么在百度上做广告推广
  • 北京 网站策划公司百度 营销怎么收费
  • 北京网站制作费用营销是做什么
  • 团购网站前景百度推广竞价是什么意思
  • 跨境b2c网站nba最新排名榜
  • 如何做简单网站发表文章的平台有哪些
  • 最好网站设计案例信阳seo推广
  • 响应式网站建设一般多少钱百度关键词竞价和收费的方法
  • 专业帮人做网站号码重庆seo报价
  • 重庆网站建设沛宣百度推广技巧
  • 建设网站具备的知识建站工具
  • 成都企业网站开发seo免费资源大全
  • 做网站渠道windows优化大师自动下载
  • 怎么做网站最便宜seo刷排名公司
  • 写网站软件网络推广销售是做什么的
  • 做网站要用什么计算机语言宁波网站建设团队
  • 网络建设上市公司排名seo服务靠谱吗
  • 做网站挂广告赚多少钱广东今天新闻最新消息
  • 网站域名注册信息推广软文范例100字
  • 网站草图怎么做seoaoo