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

不备案怎么做淘宝客网站简述优化搜索引擎的方法

不备案怎么做淘宝客网站,简述优化搜索引擎的方法,网站建设费记账,全球设计网站有哪些目录 前言: 1 左右旋 2 右左旋 3 部分细节补充 3.1 单旋和插入 3.2 部分小函数 前言: AVL树作为一种结构,理解树的本身是不大难的,难的在于,树旋转之后的连接问题,写AVL树的代码大部分都是在旋转部分…

目录

前言:

1 左右旋

2 右左旋

3 部分细节补充

3.1 单旋和插入

3.2 部分小函数


前言:

AVL树作为一种结构,理解树的本身是不大难的,难的在于,树旋转之后的连接问题,写AVL树的代码大部分都是在旋转部分,所以连接问题是比较需要细心的,那么这里来说呢,把细心做好,变量的位置放好,连接的次序连接对,就成功了。


1 左右旋

前文提及,什么情况下需要左右旋?即不是纯粹的左边高或者是右边高,那么使用到左右旋的情况如下:

如果我们固执的以为在b 或者 c插入数据之后,90的平衡因子变为了-2,右旋就能解决问题的话就完蛋啦,这里我们直接对90右旋之后,结果就是镜像的,树还是没有平衡,那么我们再左旋,相当于旋转回来了,整个树的结果是没有变的。

此时就需要左旋转后再右旋转,可能有人会问,这个图是什么意思,我们使用的是抽象图来介绍,这样更加方便,长方形代表的就是高度为多少的子树。

选择b c作为例子,当我们往b c插入数据的时候,90的平衡因子变为了-2,此时parent就是90,那么我们需要一个操作让该树变成完全的左子树高,这样再右旋转,才可以保持平衡,那么如何变成完全的左子树高呢?

记住那两个线,30 -90 30 -60的这两条线,只要60在30和90的中间就是完全的左子树高,所以我们需要对30进行左旋,所以现在已知的操作就是先左旋再右旋,要记得参数不是一样的。

旋转的问题很好解决,旋转中的问题可不止旋转,这里还有平衡因子的问题,我们不难发现,在b 或者 c插入数据之后平衡因子的改变不是一样的,甚至来说如果h = 1,即60是新插入的,平衡因子的改变也是不一样的。

所以平衡因子的变化可以分为三个情况,一是b插入,二是c插入,三是60是新插入的,其中平衡因子的变化就留给读者自己发现啦,这是比较简单的,所以代码就可以出来了:

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;subLR->_bf = 0;parent->_bf = 0;}else if(bf == -1){subL->_bf = 0;subLR->_bf = 0;parent->_bf = 1;}//60自己就是新插入的节点else if(bf == 0){subL->_bf = 0;subLR->_bf = 0;parent->_bf = 0;}else{assert(false);}

我们知道,以某个节点作为平衡节点,平衡之后该节点的父节点平衡因子必定为0,所以我们可以把subLR = 0直接提取出来。所以双旋来说是很简单,甚至比单旋都简单。


2 右左旋

有了左右旋的基础,这里直接就给代码了:

	void RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;//旋转完成RotateR(subR);RotateL(parent);//更新平衡因子subRL->_bf = 0;//RL必平衡if (bf == 1){subR->_bf = 0;parent->_bf = -1;}else if (bf == -1){parent->_bf = 0;subR->_bf = 1;}else if (bf == 0){parent->_bf = 0;subR->_bf = 0;}else{assert(false);}}

3 部分细节补充

是不是以为AVL树到这里就要结束了?

错辣!还有许多细节要注意!

3.1 单旋和插入

单旋这里除了要注意旋转的时候的连接问题,还要注意变量的声明次序问题:

	Node* subL = parent->_left;Node* subLR = subL->_right;subL->_right = parent;parent->_left = subLR;Node* pparent = parent->_parent;parent->_parent = subL;

以右旋为例子,当parent节点不是根节点,势必涉及到parent的父节点的连接问题,所以我们先声明了pparent,如果我们在这个if里面声明:

if (parent == _root){_root = subL;_root->_parent = nullptr;}else{if (parent == pparent->_left){pparent->_left = subL;}else{pparent->_right = subL;}subL->_parent = pparent;}

在此之前pparent的值就已经变为了subL,所以pparent一定要在parent->_parent =  subL之前声明了。

其次,插入这里:

//更新平衡因子
cur->_parent = parent;
while (parent)
{if (parent->_left == cur){parent->_bf--;}else{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 == 2 && cur->_bf == 1){RotateL(parent);}else if (parent->_bf == 2 && cur->_bf == -1){RotateRL(parent);}else if (parent->_bf == -2 && cur->_bf == 1){RotateLR(parent);}break;}else{//理论而言不可能出现这种情况assert(false);}
}

为什么旋转之后就要break了呢?按道理来说,比如双旋之后,parent的位置必然改变,可能直接变成了叶子节点,如果再走循环,平衡因子必然改变,此时树的结构就被破坏了,所以一定要break了。

现在解释上文说的,为什么旋转之后,比如单旋,平衡因子一定变为0了?这里我们就借助抽象图来理解,具象图没有那么好理解:

以这个图作为例子,c插入数据之后,n成为了新的根节点,此时左子树的高度是 h(m) + h  = h + 1,右子树的高度是h + 1,1是新插入的数据,所以平衡因子必定为0,该结论在左右双旋里面也有体现。

3.2 部分小函数

这里的函数就是用来测试的函数,没有什么值得特别注意的:

	void InOrder(){_InOrder(_root);cout << endl;}bool IsBalance(){return _IsBalance(_root);}int Height(){return _Height(_root);}int Size(){return _Size(_root);}private:void _InOrder(Node* root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_kv.first << " ";_InOrder(root->_right);}int _Size(Node* root){return root == nullptr ? 0 : _Size(root->_left) + _Size(root->_right) + 1;}int _Height(Node* root){if (root == nullptr)return 0;return max(_Height(root->_left), _Height(root->_right)) + 1;}bool _IsBalance(Node* root){if (root == nullptr)return true;int leftHeight = _Height(root->_left);int rightHeight = _Height(root->_right);// 不平衡if (abs(leftHeight - rightHeight) >= 2){cout << root->_kv.first << endl;return false;}// 顺便检查一下平衡因子是否正确if (rightHeight - leftHeight != root->_bf){cout << root->_kv.first << endl;return false;}return _IsBalance(root->_left)&& _IsBalance(root->_right);}

测试代码:

void TestAVLTree1()
{int arr[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };//int arr[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };AVLTree<int, int> t1;for (auto e : arr){if (e == 13){int i = 0;}t1.Insert({ e,e });cout << "Insert:" << e << "->" << t1.IsBalance() << endl;}t1.InOrder();cout << t1.IsBalance() << endl;
}void TestAVLTree2()
{const int N = 100000000;vector<int> v;v.reserve(N);srand((unsigned)time(0));for (size_t i = 0; i < N; i++){v.push_back(rand() + i);}size_t begin2 = clock();AVLTree<int, int> t;for (auto e : v){t.Insert(make_pair(e, e));cout << "Insert:" << e << "->" << t.IsBalance() << endl;}size_t end2 = clock();cout << "Insert:" << end2 - begin2 << endl;cout << "Height:" << t.Height() << endl;cout << "Size:" << t.Size() << endl;size_t begin1 = clock();// 确定在的值for (auto e : v){t.Find(e);}//随机值for (size_t i = 0; i < N; i++){t.Find((rand() + i));}size_t end1 = clock();cout << "Find:" << end1 - begin1 << endl;
}

下场剧透~因为AVL树的查找实在太快,但是对于平衡因子的控制要求太严格了,所以红黑树出现了,红黑树是一种近似平衡的结构~ 


感谢阅读!

http://www.wooajung.com/news/21863.html

相关文章:

  • 手机动态网站制作今日国内新闻摘抄十条
  • 兴义之窗网站怎么做怎么查百度搜索排名
  • 郑州网站建设网络公司网络广告策划书模板范文
  • 南通网站排名优化福州专业的seo软件
  • 怎么把网站封包做app企业营销策划有限公司
  • 网站建设六道东莞网站公司哪家好
  • 北滘网站建设百度小说排行榜风云榜单
  • 文化传媒网站php源码培训班该如何建站
  • 做presentation的网站百度关键词工具
  • 网站建设 制作公司免费平台推广
  • 网站做微信支付接口百度官方网首页
  • bs架构网站开发前台技术郑州网站关键词优化公司
  • 企业是做app还是做网站网络营销推广的方法
  • 网站推广渠道怎么做网络平台推广具体是怎么推广
  • 重庆做网站推广的网络销售好不好做
  • 做推广的网站吗2022年最新新闻播报稿件
  • 国内做网站最大的公司有哪些百度小说风云榜今天
  • 日照蝶恋花网站建设如何引流推广
  • 怎么介绍自己做的电影网站吗杭州seo排名优化
  • 南京的电商网站设计深圳市seo点击排名软件价格
  • 网站建设难点广州优化公司哪家好
  • wordpress 手机 自建站网站推广网络营销
  • 如何做网站广告图片广州网站设计
  • 做物流用哪个网站好seo专员是干什么的
  • 建设银行官方网站诚聘英才频道免费的推广软件下载
  • wps2016怎么做网站怎么自己找外贸订单
  • 如何做webgis网站手机网页设计制作网站
  • 海外网站代购的方案b2b商务平台
  • 域名备案的网站建设方案书模板中国搜索引擎排名
  • 浙江省城乡住房建设部网站安徽百度seo教程