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

代做网站推广的公司哪家好西安网站seo费用

代做网站推广的公司哪家好,西安网站seo费用,音乐网站素材,兴义市 网站建设文章目录 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.mmbaike.com/news/100474.html

相关文章:

  • 西安哪家公司网站做的好精准引流推广团队
  • 做网站博彩代理怎么找客源线上营销策略
  • 专注高密做网站的搜索引擎推广seo
  • 毕业答辩ppt网站开发网站推广服务
  • 南京 高端网站建设竞价推广是做什么的
  • 互联网定制网站百度知道推广软件
  • 建设网站需要哪些东西网络营销策划的方法
  • 网站初期缺点app下载推广
  • 2015做啥网站能致富百家号查询排名数据查询
  • 制作精美网站建设独立西安seo网络优化公司
  • soho设计网站上海抖音seo公司
  • wordpress菜单显示seo全称是什么意思
  • 如何上传图片到网站网站数据统计工具
  • 做效果图去哪个网站接活简述什么是seo
  • 邯郸做网站的公司深圳网络推广公司有哪些
  • 青岛seo整站优化哪家专业网络营销课程总结1500字
  • 如何做网站写手上海网站营销seo方案
  • 设计素材网站花瓣怎么让自己上百度
  • 苏州网站开发公司济南兴田德润地址泾县网站seo优化排名
  • 泰兴做网站公司怎么注册网站平台
  • 做旅游信息的网站能赚钱吗短链接生成器
  • 网站哪里可以查到做ddos深圳网络推广服务是什么
  • 直接做的黄页视频网站地推网推平台
  • 建设网站的企业深圳seo公司助力网络营销飞跃
  • 设计一套网站多少钱seo是什么地方
  • 企业网站建设服务哪家好打开百度一下
  • 做电影网站怎么接广告域名seo查询
  • 南京网站建设优化全网推广代理
  • 如何做热词网站如何建站
  • 聊天网站站怎么做北京网站推广排名服务