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

做网站用的幻灯片大小湖北seo关键词排名优化软件

做网站用的幻灯片大小,湖北seo关键词排名优化软件,盗版视频网站怎么做,网站推广平台有哪些前言 紧接着上一篇文章,我们来模拟实现一下set的底层结构 引入 对于BSTree,虽然可以缩短查找的效率,但如果数据有序它将退化为单支树 我们可以用AVL树来解决这个问题。 概念 AVL树: 它的每个结点的左右子树高度之差的绝对值…

前言

紧接着上一篇文章,我们来模拟实现一下set的底层结构

引入

对于BSTree,虽然可以缩短查找的效率,但如果数据有序它将退化为单支树

我们可以用AVL树来解决这个问题。

概念

AVL树:

  • 它的每个结点的左右子树高度之差的绝对值不超过1
  • 它的左右子树都是AVL树

在这里插入图片描述对于10来说,左右子树高度差为2,所以不满足

实现

基本结构

template<class K, class V>
struct AVLTreeNode
{using Node = AVLTreeNode<K, V>;Node* _left;	//左节点Node* _right;	//右节点Node* _parent	//父节点int _bf;		//平衡因子//计算方式:右树高度减去左树高度pair<K, V> _kv;	//用pair封起来的键值对AVLTreeNode(const pair<K, V>& kv):_kv(kv),_bf(0),_left(nullptr),_right(nullptr),_parent(nullptr){}
};

插入

和搜索树的插入规则前半部分是相同的,具体细节可以看注释

	bool Insert(const pair<K, V>& kv){//1.按照搜索树规则插入:先找到合适的位置,然后链接if (_root == nullptr){_root = new Node(kv);return true;}//如果树为空,特殊判断Node* parent = nullptr;//父节点//方便记录父节点原来的子树Node* cur = _root;while (cur != nullptr){if (cur->kv.first > kv.first){parent = cur;cur = cur->_left;}else if (cur->kv.first < kv.first){parent = cur;cur = cur->_right;}else{return false;}}//查找完再判断是父节点的左树还是右数//标记为Acur = new Node(kv);if (parent->kv.first > kv.first){parent->_right = cur;}else{parent->_right = cur;}cur->_parent = parent;//2.更新平衡因子,根据AVL的规则,进行旋转调整//	- 插入因子会影响自己所有的祖先节点//	- 更新原则://		1.修改_bf//			- cur是_parent左边,_parent->_bf--//			- cur是_parent右边,_parent->_bf++//		2.根据_parent->_bf是否为0来判断是否修改祖先的_bf,//			- _bf == 0 在更新前_bf是-1或1,更新后左右平衡了,所以不会影响祖先//			- _bf == 1/-1 更新前平衡因子为0,更新后左右不平衡了,所以祖先也要更新//		3._bf == 2/-2 插入后出现问题,要进行旋转while(parent){if (parent->_right == cur){parent->_bf++;}else{parent->_bf--;}if (parent->_bf == 0){break;}else if (parent->_bf == 1 || parent->_bf == 1){cur = cur->_parent;parent = parent->_parent;}else if (parent->_bf == 2 || parent->_bf == -2){if (parent->_bf == 2 && cur->_bf == 1){RotateL(parent);}else if(parent->_bf == -2 && cur->_bf == -1){RotateR(parent);}else if (parent->_bf == -2 && cur->_bf == 1){RotateLR(parent);}else{RotateRL(parent);}break;//因为旋转完就是全都平衡了,所以直接结束循环}else{throw("false");}}return true;}

旋转

旋转也是插入的一部分,只是因为比较重要,所以单独拎出来写

变量说明:

  • h表示树的高度
  • a、b、c是树的名字
  • 30,60是_value

左单旋

在这里插入图片描述
左单旋适合的情况:
右树插入新的节点,导致祖先节点不平衡

操作:

  1. 将右节点的左子树变为祖先节点的右子树
  2. 将祖先节点变为父节点的左子树
void RotateL(Node* parent)			//右单旋
{Node* subR = parent->_right;	//subR是parent的右节点Node* subRL = subR->_left;		//subRL是subR的左节点parent->_right = subRL;if (subRL){subRL->_parent = parent;}subR->_left = parent;parent->_parent = subR;if (parent == _root){_root = subR;subR->_parent = nullptr;}else{if (parent->_parent->_left == parent){parent->_parent->_left = subR;}else{parent->_parent->_right = subR:}subR->_parent = parent->_parent;}parent->_bf = 0;subR->_bf = 0;
}

右单旋

和上面的逻辑相同,只是新增节点放在了左子树,要向右旋转

	void RotateR(Node* parent)			//右单旋{Node* subL = parent->_left;		//subL是parent的左节点Node* subLR = subL->_right;		//subLR是subL的右节点parent->_left = subLR;if (subLR){subLR->_parent = parent;}subL->_right = parent;parent->_parent = subL;if (parent == _root){_root = subL;subL->_parent = nullptr;}else{if (parent->_parent->_left == parent){parent->_parent->_left = subL;}else{parent->_parent->_right = subL:}subL->_parent = parent->_parent;}parent->_bf = 0;subL->_bf = 0;}

左右双旋

旋转的代码相同,就是对于平衡因子的处理需要注意
分四种情况考虑

	void RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;RotateL(parent->_left);RotateR(parent);if (bf == -1){subLR->_bf = 0;subL->_bf = 0;parent->_bf = 1;}else if (bf == 1){subLR->_bf = 0;subL->_bf = -1;parent->_bf = 0;}else if (bf == 0){subLR->_bf = 0;subL->_bf = 0;parent->_bf = 0;}else{throw("false");}}

右左双旋

	void RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;RotateR(subR);RotateL(parent);subRL->_bf = 0;if (bf == 1){subR->_bf = 0;parent->_bf = -1;}else if (bf == -1){parent->_bf = 0;subR->_bf = 1;}else{parent->_bf = 0;subR->_bf = 0;}}

判断是否平衡

我们再写一个接口来判断给的树是否平衡

	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;}bool _IsBlance(Node* root){if (root == nullptr){return true;}int leftHeight = Height(root->_left);int rightHeight = Height(root->_right);if (abs(leftHeight - rightHeight) >= 2){throw("不平衡");}if (rightHeight - leftHeight != root->_bf){throw("平衡因子异常");}return _IsBlance(root->_left)&& _IsBlance(root->_right);}

优化:求高度

我们可以发现,这段代码还可以优化,因为每一次的高度都是要重新求的,有很多重复工作。

所以,我们可以增加一个参数,

bool _IsBlance(Node* root, int& height);

这样树的高度就会再函数调用结束后被传出来,并且不用修改返回值

	bool _IsBalance(Node* root, int& height){if (root == nullptr){height = 0;return true;}int leftHeight = 0, rightHeight = 0;if (!_IsBalance(root->_left, leftHeight) || !_IsBalance(root->_right, rightHeight)){return false;}if (abs(rightHeight - leftHeight) >= 2){cout <<root->_kv.first<<"不平衡" << endl;return false;}if (rightHeight - leftHeight != root->_bf){cout << root->_kv.first <<"平衡因子异常" << endl;return false;}height = leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;return true;}bool IsBalance(){int height = 0;return _IsBalance(_root, height);}

结语

AVL树比搜索树要更优秀,但具体逻辑(指旋转)要更复杂,希望对你有帮助!!

http://www.hkea.cn/news/846271/

相关文章:

  • 中国红河网seo排名工具
  • 做网站商丘3a汽车集团公司网络营销方案
  • 网络宣传推广策划范文seo如何优化排名
  • 网站 建设 原则新闻今天的最新新闻
  • 服装网站首页设计主要推广手段免费
  • 网站建设公司做销售好不好?seo搜索引擎优化实训总结
  • 江西威乐建设集团有限公司企业网站长春关键词优化公司
  • 深圳网站建设lxhd英文关键词seo
  • 在线购物商城网站百度移动端排名软件
  • 太原网站的公司友情链接的英文
  • 网站是用什么做的吗百度q3财报2022
  • 深圳福田网站建设公司如何做谷歌seo推广
  • 西安有做网站的吗北京网站设计公司
  • 哪家专门做特卖网站平台连接
  • 衢州网站推广最近发生的重大新闻
  • 网页设计的网站配色方案seo基础培训机构
  • 维护网站是什么工作淄博网站制作
  • 做电影下载网站成本淘宝关键词排名
  • 企业h5网站建设百度推广电话是多少
  • 中国保密在线网站培训系统软文怎么做
  • 山西住房城乡建设部网站整合网络营销是什么
  • 做美图网站有哪些东西吗个人博客seo
  • 南昌专业做网站公司竞价托管怎么做
  • 网站产品展示怎么做微信小程序建站
  • dw做网站的流程客户引流的最快方法是什么
  • 做网站app优惠活动的交换链接营销成功案例
  • 企业公示信息查询系统山西上海百度推广优化公司
  • 上海网站排名优化价格武汉百度快照优化排名
  • 做网站小程序如何做广告宣传与推广
  • 网站建设背景朝阳百度新闻网页