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

网站优化原理汕头seo网站建设

网站优化原理,汕头seo网站建设,c2c网站的特点,前端做学校网站教务AVL树是一棵平衡二叉搜索树 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查 找元素相当于在顺序表中搜索元素,效率低下 一种解决上述问题的方法:当向二叉搜索树中插入新结点后&#xff0…

AVL树是一棵平衡二叉搜索树

二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查
找元素相当于在顺序表中搜索元素,效率低下

一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度,平衡二叉搜索树就诞生了。

在这里,主要实现他的调节功能。

首先在每一个节点了都需要一个平衡因子bf,通过平衡因子判断是否平衡。

template<class T, class V >
struct AVLTreeNode
{AVLTreeNode<T,V>* _parent; // 指向其父节点AVLTreeNode<T,V>* _left;AVLTreeNode<T,V>* _right;T _key;V _value;int bf;   //  平衡因子AVLTreeNode(const T& key = T(), const V& value = V()):_parent(nullptr),_left(nullptr),_right(nullptr),_key(key),_value(value),bf(0){}
};

bf为右子树的高度减左子树的高度,也就是说,平衡搜索二叉树要保持每一个节点里的bf都小于2,大于-2。

在之前,已经实现了通过插入就可以保持一颗搜索树。

插入代码(未调节)

template<class T, class V >
class AVLTree
{typedef AVLTreeNode<T, V> AVLTreeNode;
public:AVLTree():_node(nullptr){ }bool Insert(const T& key = T(), const V& value = V()){if (_node == nullptr){_node = new AVLTreeNode(key,value);return true;}AVLTreeNode* cur = _node;AVLTreeNode* parent = nullptr;  while (cur != nullptr){if (cur->_key == key){return false; }if (cur->_key > key){parent = cur;cur = cur->_left;}else{parent = cur;cur = cur->_right;}}if (key < parent->_key){parent->_left = new AVLTreeNode(key, value);parent->_left->_parent = parent;}else{parent->_right = new AVLTreeNode(key, value);parent->_right->_parent = parent;}

接下来就是对平衡因子的判断的对树的调节,因为当我们插入一个节点,其祖先节点可能都会发生改变。

可以看出,当插入一个节点时,其祖先节点可能受影响,其他节点不受影响。

只需要向上调节并排查祖先的平衡因子。当某个祖先的平衡因子bf==0的时候结束。

如何调节祖先的平衡因子与为什么bf==0就结束呢?

蓝色方框表示将要插入的节点

这里的bf指2的bf。

图一,bf==1,左插入后,bf==0。

图二,bf==-1,右插入后,bf=0。

图三,bf==0,右插入后,bf=1。

图四,bf==0,左插入后,bf=-1。

可以发现,左插入,bf--,右插入,bf++

当插入后bf==0,其所有祖先的高度并没有被影响。

当插入后bf==1/-1,就要去向上判断祖先是否被影响,图三,图四(2的父节点)的bf均改变,变为了1,图五2的父节点的bf变为2,需要调节了。

写一下向上的代码

		while (parent){if (parent->_key > key) // 通过key判断改变的是parent的左边还是右边{parent->bf--;}else{parent->bf++;}if (parent->bf == 0)      //  原来是1或-1,说明并没有改变高度{break;}else if (parent->bf == 1 || parent->bf == -1)     //  原来是为0 ,其所有的祖先都可能被影响了{                                //   往上走,判断其祖先cur = parent;parent = parent->_parent;}//   开始旋转else if((parent->bf == 2 || parent->bf == -2))}

看看是如何旋转的

将bf==2/-2的节点定义为parent,上调之前的parent定义为cur(cur->_parent==parent)

左旋转:将cur->left给parent->right(原来cur是parent->right),parent变为cur->left。

右旋转:将cur->right给parent->left(原来cur是parent->left),parent变为cur->right。

注意,这里也很复杂,需要考虑他们的_parent节点的连接和parent是否是头节点。

接下来具体讲一讲他们的分类

bf==1/-1继续往上走,看父节点的bf变化。

旋转一经过左旋转后就可以break了

旋转二就要复杂一点,看看旋转二的分析

可以看到在parent->bf==2,cur->bf==-1,需要双旋的,需要将左右旋结合。

左单旋

    //左单旋void RotateL(AVLTreeNode* parent){if (parent == nullptr || parent->_right == nullptr)return;AVLTreeNode* subr = parent->_right;AVLTreeNode* subrL = subr->_left;    //记录,保证对cur->bf的正确修改parent->_right = subr->_left;if (subr->_left){subr->_left->_parent = parent;}subr->_left = parent;AVLTreeNode* ppnode = parent->_parent;parent->_parent = subr;//对subr进行处理if (ppnode == nullptr)    //  parent是头节点{subr->_parent = nullptr;_node = subr;}else{subr->_parent = ppnode;if (ppnode->_left == parent){ppnode->_left = subr;}else{ppnode->_right = subr;}}//  进行bf的修改if (parent->bf == 2){if (subr->bf == 1){parent->bf = subr->bf = 0;}if (subr->bf == -1){if (subrL->bf == 0){parent->bf = subrL->bf = subr->bf = 0;}if (subr->bf == -1){parent->bf = subrL->bf = 0;subr->bf = 1;}}}}

右单旋

	void RotateR(AVLTreeNode* parent){if (parent == nullptr){return;}AVLTreeNode* subl = parent->_left;AVLTreeNode* sublR = subl->_right;parent->_left = subl->_right;if (subl->_right)  //  为空就不用去管他的_parent{subl->_right->_parent = parent;}subl->_right = parent;AVLTreeNode* ppnode = parent->_parent;parent->_parent = subl;if (ppnode == nullptr){subl->_parent = nullptr;}else{subl->_parent = ppnode;if (ppnode->_left == parent){ppnode->_left = subl;}else{ppnode->_right = subl;}}if (parent->bf == -2){if (subl->bf == -1){subl->bf = parent->bf = 0;}if (subl->bf == 1){if (sublR->bf == 0){parent->bf = sublR->bf = subl->bf = 0;}if (sublR->bf == 1){parent->bf = sublR->bf = 0;subl->bf = -1;}}}}

旋转代码

			//   开始旋转else if((parent->bf == 2 || parent->bf == -2)){if (parent->bf == 2){if (cur->bf == 1){RotateL(parent);}if (cur->bf == -1){RotateR(cur);    //  不会给平衡因子,因为cur->parent!=-2RotateL(parent);}}if (parent->bf == -2){if (cur->bf == -1){RotateR(parent);}if (cur->bf == 1){RotateL(cur);      //  不会给平衡因子,因为cur->parent!=-2RotateR(parent);}}break;    //   旋转了就保证了当前的树是平衡树,其祖先不需要判断了}

对代码进行测试

	void _InOrder(AVLTreeNode* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " " << root->_value << endl;_InOrder(root->_right);}void InOrder(){_InOrder(_node);}bool _IsbalanceTree(AVLTreeNode* root, int& high){if (root == nullptr){high = 0;return true;}int left_high = 0;if (_IsbalanceTree(root->_left, left_high) == false){return false;}int right_high = 0;if (_IsbalanceTree(root->_right, right_high) == false){return false;}if (left_high - right_high > 1 || left_high - right_high < -1){return false;}high = 1 + (left_high > right_high ? left_high : right_high);return true;       //   满足左子树为平衡二叉树   右子树为平衡二叉树  该树为平衡二叉树}//判断平衡bool IsbalanceTree(){int k = 0;return _IsbalanceTree(_node, k);}
void test4()
{AVLTree<string, int> avl;avl.Insert("a", 1);avl.Insert("b", 2);avl.Insert("c", 3);avl.Insert("d", 4);avl.Insert("e", 5);avl.Insert("f", 6);avl.Insert("g", 7);avl.Insert("h", 8);avl.Insert("i", 9);avl.Insert("j", 10);//判断是否是平衡二叉搜索树// 搜索树avl.InOrder();// 平衡树if (avl.IsbalanceTree()){cout << "是平衡树" << endl;}
}结果:
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10
是平衡树

其实在耦合这块的话并不是很好,将左右旋和右左旋单独实现并修改平衡因子能够实现高内聚,低耦合。

希望能够彻底帮助你理解AVL树的旋转,而不是仅依靠一张结论图搬公式!!!


文章转载自:
http://dinncorailroading.stkw.cn
http://dinncoturbomolecular.stkw.cn
http://dinncounderbidder.stkw.cn
http://dinncobunyan.stkw.cn
http://dinncomedicinable.stkw.cn
http://dinncohominoid.stkw.cn
http://dinncopyorrhea.stkw.cn
http://dinncoparonychia.stkw.cn
http://dinncoorienteer.stkw.cn
http://dinncokelter.stkw.cn
http://dinncorecruit.stkw.cn
http://dinncooleum.stkw.cn
http://dinncoexegetics.stkw.cn
http://dinncocoincidence.stkw.cn
http://dinncomonophyletic.stkw.cn
http://dinncoccis.stkw.cn
http://dinncobluffness.stkw.cn
http://dinncochuffed.stkw.cn
http://dinncomicrointerrupt.stkw.cn
http://dinncorutherford.stkw.cn
http://dinncocustomable.stkw.cn
http://dinncosheafer.stkw.cn
http://dinncopigmy.stkw.cn
http://dinncolacedaemonian.stkw.cn
http://dinncojustifier.stkw.cn
http://dinncoozonesonde.stkw.cn
http://dinncoconflagrant.stkw.cn
http://dinncojalalabad.stkw.cn
http://dinncoprussianize.stkw.cn
http://dinncohemostatic.stkw.cn
http://dinncoinsolubility.stkw.cn
http://dinncobaleen.stkw.cn
http://dinncopackboard.stkw.cn
http://dinncogroovelike.stkw.cn
http://dinncoorientate.stkw.cn
http://dinncobackwater.stkw.cn
http://dinncohusbandman.stkw.cn
http://dinncoimmethodical.stkw.cn
http://dinncoforeshore.stkw.cn
http://dinncocurly.stkw.cn
http://dinncoclosing.stkw.cn
http://dinncomutely.stkw.cn
http://dinncoimpone.stkw.cn
http://dinncosergeantship.stkw.cn
http://dinncosnook.stkw.cn
http://dinncocofeature.stkw.cn
http://dinncogeodetic.stkw.cn
http://dinncosucculent.stkw.cn
http://dinncosleeveless.stkw.cn
http://dinncolevelling.stkw.cn
http://dinncocoil.stkw.cn
http://dinncokaliph.stkw.cn
http://dinncovoyeurism.stkw.cn
http://dinncorecontaminate.stkw.cn
http://dinncostory.stkw.cn
http://dinncodiaphone.stkw.cn
http://dinncospaceward.stkw.cn
http://dinncoblusterous.stkw.cn
http://dinncojune.stkw.cn
http://dinncoandrea.stkw.cn
http://dinncopanel.stkw.cn
http://dinncononmaterial.stkw.cn
http://dinnconeuter.stkw.cn
http://dinncolaevorotary.stkw.cn
http://dinncofasti.stkw.cn
http://dinncoall.stkw.cn
http://dinncoviol.stkw.cn
http://dinncomycosis.stkw.cn
http://dinnconeoterize.stkw.cn
http://dinncomilkman.stkw.cn
http://dinncodls.stkw.cn
http://dinncowestmorland.stkw.cn
http://dinncofluster.stkw.cn
http://dinncoposteriority.stkw.cn
http://dinncohcs.stkw.cn
http://dinncopleasurable.stkw.cn
http://dinncoentremets.stkw.cn
http://dinnconightcapped.stkw.cn
http://dinncojacana.stkw.cn
http://dinncobunny.stkw.cn
http://dinncoeloise.stkw.cn
http://dinncoprecautionary.stkw.cn
http://dinnconontuplet.stkw.cn
http://dinncodynam.stkw.cn
http://dinncoaubergine.stkw.cn
http://dinncosemidivine.stkw.cn
http://dinncoxerotic.stkw.cn
http://dinncohalfway.stkw.cn
http://dinncomuss.stkw.cn
http://dinncoptolemaic.stkw.cn
http://dinncotachyhydrite.stkw.cn
http://dinncoma.stkw.cn
http://dinnconouvelle.stkw.cn
http://dinncoragpicker.stkw.cn
http://dinncogrocery.stkw.cn
http://dinncooutjockey.stkw.cn
http://dinncoreturnee.stkw.cn
http://dinncogruntling.stkw.cn
http://dinncobiodegradable.stkw.cn
http://dinnconazir.stkw.cn
http://www.dinnco.com/news/92454.html

相关文章:

  • saas平台seo网站推广多少钱
  • 医院网站后台管理系统登录如何搭建个人网站
  • PK10如何自己做网站百度合伙人官网app
  • 嘉兴建设局网站广州aso优化
  • 有网站后台模板如何做数据库怎么找需要做推广的公司
  • 自己做的网站怎么接入网页游戏谷歌浏览器官网手机版
  • 个人网站如何获得流量上海快速优化排名
  • 公司注册地址在外地却在本地经营汉川seo推广
  • 装饰公司网站北京网站优化指导
  • wordpress前台代码编辑器上海网站seo公司
  • 规划建立一个网站百度快照网址
  • 嘉兴公司制作网站的如何营销
  • 个人 申请域名做网站中山seo推广优化
  • wordpress自动同步插件怀来网站seo
  • 网站建设 价格百度推广效果怎么样
  • 吉化北建公司官网西青seo
  • 做网站原创要多少钱外贸快车
  • 做网站交互demo工具唐山seo优化
  • 网站的开发环境设计美国seo薪酬
  • 淮北网站建设网上销售平台有哪些
  • 去哪个网站有客户找做标书的2023年10月疫情还会严重吗
  • 网站排名带照片怎么做中公教育培训机构官网
  • 用asp制作一个简单的网站微指数查询
  • 网站建设v地推平台去哪里找
  • 武汉门户网站建设网络的推广
  • 吉林建设厅网站网站搜什么关键词好
  • 网站备案要多久推广策略都有哪些
  • 做网址导航网站收益北京网络推广优化公司
  • 用dw怎么做网站后台优化大师免费安装下载
  • 宁波网站建设公司费用价格网站都有哪些