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

如何选择手机网站建设潍坊网站外包

如何选择手机网站建设,潍坊网站外包,博罗惠州网站建设,部队网站建设多少钱目录 一、红黑树概念 二、红黑树节点结构设计 三、插入操作 处理情况1 处理情况2 处理情况3 插入总结: 四、插入操作源码 五、红黑树验证 一、红黑树概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色&#xff0…

目录

一、红黑树概念

 二、红黑树节点结构设计

三、插入操作

 处理情况1

 处理情况2

处理情况3

 插入总结:

 四、插入操作源码

五、红黑树验证


一、红黑树概念

 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍(由规则二三四来保证),因而是接近平衡的。因为最长路径为一黑一红,最短路径为全黑。

 红黑树还必须满足以下规则:

1. 每个结点不是红色就是黑色(非红即黑)
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的(没有连续的红色)
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点(每条路径上黑色节点的数量相等)(从这一规则也可以得出,在插入一新节点时,该节点必须为红,才会满足该条件)
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点

 规则四演示:

 二、红黑树节点结构设计

 因为红黑树节点非红即黑,所以可以用枚举的思想来例举红节点和黑节点。因为在插入的过程中,可能会存在翻转的情况,所以就需要一个节点的父节点_parent,左孩子_left,右孩子_right。

enum Colour
{RED,BLACK
};template<class K, class V>
struct RBTreeNode
{ RBTreeNode<K, V>* _left;  // 左孩子RBTreeNode<K, V>* _right;  // 右孩子RBTreeNode<K, V>* _parent;  // 红黑树需要旋转,为了实现简单给出该字段pair<K, V> _kv;  //值域Colour _col;  //颜色RBTreeNode(const pair<K, V>& kv)  //初始化:_left(nullptr), _right(nullptr), _parent(nullptr), _kv(kv){}
};

三、插入操作

根据规则4,可以得出在插入一个新节点的时候,这个节点一定是为红色的(上已证)。在插入红色节点的时候可能还是会造成红红节点的冲突(违反规则3),所以我们还需要进行变色+旋转的处理方法

 在插入新节点后,因为新节点的默认颜色是红色,因此:如果其父亲节点的颜色是黑色,没有违反红黑树任何规则,则不需要调整;但当新插入节点的父亲节点颜色为红色时,就违反了规则3不能有连在一起的红色节点,此时需要对红黑树分情况来讨论:为方便我们进行变色和旋转的处理,我们定义父亲节点为p,叔叔节点为u,祖父节点为g,当前节点为cur(新增)。实际上,根据红黑树的规则,我们可以确定要发生变色或旋转操作时,cur、p、g节点一定是红、红、黑,如果不满足这种情况,那么肯定这颗红黑树在次之前就违背的红黑树的规则。所以变化操作主要取决于叔叔节点u的颜色。如下抽象图表示,s/b/c/de代表的是满足规则的子树。

 

 处理情况1

cur为红,p为红,g为黑,u存在且为红

 处理方法:叔叔u和父亲p变黑,祖父g变红,再往上进行处理,如果g是根节点,需要把g再变黑,因为根节点必须是黑(规则2)。再往上处理的过程中因为会存在当前g的父节点为红的情况,又再次冲突,所以要进行处理.

 

 

 处理情况2

cur为红且在外侧,p为红,g为黑,u不存在/u存在且为黑

u的两种情况:

1.如果u节点不存在,则cur一定是新插入节点,因为如果cur不是新插入节点,则cur和p一定有一个节点的颜色是黑色,就不满足性质4:每条路径黑色节点个数相同。

 

⒉.如果u节点存在,则其一定是黑色的,那么cur节点原来的颜色一定是黑色的,现在看到其是红色的原因是因为cur的子树在调整的过程中将cur节点的颜色由黑色改成红色。
 

 

 处理方法:单旋+变色。按p节点进行右旋,此时p为红,g为黑,再将p和g的颜色进行交换,即满足红黑树规则。(若p为g的右孩子,cur为p的右孩子,则进行左单旋转,p、g变色--p变黑,g变红)。处理完成后不需要再进行往上处理,因为此时p为黑,p的父亲节点为黑或红都不会对树产生影响。

处理情况3

cur为红且在内侧,p为红,g为黑,u不存在/u存在且为黑

 处理方法:双旋+变色

u不存在情况:

若p在g的左侧,cur在内侧,则先对g的左子树进行左旋,在对g这棵子树进行右旋;反之,p在g的右侧,cur在内存,就先右旋再左旋再交换cur和g的颜色。

 u存在情况:

像这种情况,都是由情况一经过处理后得来的,此时就需要先对g的左子树进行左单旋,旋转后,就会变为情况二,此时再根据情况二的解决方法进行解决,右旋+变色,旋转后将cur和g的颜色进行交换即可。(如果最开始p是在右子树,则操作相反,先右旋再左旋变色。)

 插入总结:

1.红黑树插入的节点一定为红色

2.处理三种可能的情况关键在于叔叔节点u

3.u存在且为红(情况一),将p和u节点变黑,g节点变红,若g为根节点就将g变为黑色

4.情况二和情况三都是由情况一经过变化后得来的

4.u不存在或存在且为黑,插入的节点cur在p的外侧(情况二),若p是左子树就进行右旋+交换p、g颜色;若p是右子树,反之,左旋+交换颜色。

5.u不存在或存在且为黑,插入节点cur在p的内侧(情况三),若p是左子树就先进行左旋变为情况二,再进行右旋+交换颜色。反之p为右子树,先进行右旋变为情况二,在进行左旋+交换颜色。

 四、插入操作源码

插入源码: 

	bool Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_kv.first < kv.first){parent = cur;cur = cur->_right;}else if (cur->_kv.first > kv.first){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(kv);cur->_col = RED;if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;while (parent && parent->_col == RED)  // parent为红色就需要变色处理,因为插入的节点为红{Node* grandfater = parent->_parent;  //祖父节点assert(grandfater);assert(grandfater->_col == BLACK);// 关键看叔叔if (parent == grandfater->_left){Node* uncle = grandfater->_right;  //叔叔节点// 情况一 : uncle存在且为红,变色+继续往上处理if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfater->_col = RED;// 继续往上处理cur = grandfater;  // 往上处理的时候把祖父当做插入的节点即curparent = cur->_parent;}// 情况二+三:uncle不存在 + 存在且为黑else{// 情况二:右单旋+变色//     g //   p   u// cif (cur == parent->_left){RotateR(grandfater);parent->_col = BLACK;grandfater->_col = RED;}else{// 情况三:左右单旋+变色//      g //   p     u//     cRotateL(parent);RotateR(grandfater);cur->_col = BLACK;grandfater->_col = RED;}break;}}else // (parent == grandfater->_right){Node* uncle = grandfater->_left;// 情况一if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfater->_col = RED;// 继续往上处理cur = grandfater;parent = cur->_parent;}else{// 情况二:左单旋+变色//     g //   u   p//         cif (cur == parent->_right){RotateL(grandfater);parent->_col = BLACK;grandfater->_col = RED;}else{// 情况三:右左单旋+变色//     g //   u   p//     cRotateR(parent);RotateL(grandfater);cur->_col = BLACK;grandfater->_col = RED;}break;}}}_root->_col = BLACK;return true;}

旋转操作的源码解析可以参考这篇博文:http://t.csdn.cn/iyMac

左旋:

	void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;Node* ppNode = parent->_parent;subR->_left = parent;parent->_parent = subR;if (_root == parent){_root = subR;subR->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = subR;}else{ppNode->_right = subR;}subR->_parent = ppNode;}}

右旋:

	void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR){subLR->_parent = parent;}Node* ppNode = parent->_parent;subL->_right = parent;parent->_parent = subL;if (_root == parent){_root = subL;subL->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = subL;}else{ppNode->_right = subL;}subL->_parent = ppNode;}}

五、红黑树验证

验证方法:判断从根节点起的每一条子路径中的黑节点数是否相等(规则4)。利用递归的思想遍历每一条路径。再遍历第一条路径的时候,设置一个benchmark记录黑色节点数量,因为规则4,所以后面每一条路径的黑节点数应该都要与之相等,如果不等则不是红黑树。再遍历每一条路径的同时,也可以寻找是否存在连续的红节点(规则三),存在则不满足为红黑树。依次递归每一条路径。

源码:

	bool IsBalance(){if (_root == nullptr){return true;}if (_root->_col == RED){cout << "根节点不是黑色" << endl;return false;}// 黑色节点数量基准值int benchmark = 0;return PrevCheck(_root, 0, benchmark);}bool PrevCheck(Node* root, int blackNum, int& benchmark){if (root == nullptr){if (benchmark == 0)  // 遍历第一条路径的时候,记录他的黑节点数,后面每一条路径的黑节点数一个都和他相等{benchmark = blackNum;return true;}if (blackNum != benchmark){cout << "某条黑色节点的数量不相等" << endl;return false;}else{return true;}}if (root->_col == BLACK){++blackNum;}if (root->_col == RED && root->_parent->_col == RED){cout << "存在连续的红色节点" << endl;return false;}return PrevCheck(root->_left, blackNum, benchmark)&& PrevCheck(root->_right, blackNum, benchmark);}void TestRBTree()
{size_t N = 1000;srand(time(0));RBTree<int, int> t1;for (size_t i = 0; i < N; ++i){int x = rand();cout << "Insert:" << x << ":" << i << endl;t1.Insert(make_pair(x, i));}cout << "IsBalance:" << t1.IsBalance() << endl;  //打印1则是红黑树,否则不是
}


文章转载自:
http://countermark.dztp.cn
http://muskeg.dztp.cn
http://preussen.dztp.cn
http://isogenic.dztp.cn
http://uplink.dztp.cn
http://luminometer.dztp.cn
http://unceremoniously.dztp.cn
http://thessaly.dztp.cn
http://mydriatic.dztp.cn
http://ninogan.dztp.cn
http://futuramic.dztp.cn
http://thimble.dztp.cn
http://beach.dztp.cn
http://gastrohepatic.dztp.cn
http://cockatoo.dztp.cn
http://haft.dztp.cn
http://haematogenous.dztp.cn
http://evincible.dztp.cn
http://snowslide.dztp.cn
http://decahedron.dztp.cn
http://wuhu.dztp.cn
http://recollect.dztp.cn
http://orionid.dztp.cn
http://ranchero.dztp.cn
http://stateswoman.dztp.cn
http://iatrogenesis.dztp.cn
http://prostacyclin.dztp.cn
http://imaginary.dztp.cn
http://routing.dztp.cn
http://gyri.dztp.cn
http://humberside.dztp.cn
http://alogical.dztp.cn
http://tergum.dztp.cn
http://markan.dztp.cn
http://befoul.dztp.cn
http://expunction.dztp.cn
http://inaptness.dztp.cn
http://fripper.dztp.cn
http://protector.dztp.cn
http://thing.dztp.cn
http://dewiness.dztp.cn
http://expansile.dztp.cn
http://centralist.dztp.cn
http://haoma.dztp.cn
http://hypoalonemia.dztp.cn
http://quintain.dztp.cn
http://toastmaster.dztp.cn
http://friendly.dztp.cn
http://bestiary.dztp.cn
http://zincy.dztp.cn
http://shansi.dztp.cn
http://regedit.dztp.cn
http://logging.dztp.cn
http://grittiness.dztp.cn
http://aconitase.dztp.cn
http://assemblyman.dztp.cn
http://commonly.dztp.cn
http://lacomb.dztp.cn
http://acidhead.dztp.cn
http://deplete.dztp.cn
http://anisotropism.dztp.cn
http://parang.dztp.cn
http://potshot.dztp.cn
http://hemofuscin.dztp.cn
http://kerygma.dztp.cn
http://centennially.dztp.cn
http://adnate.dztp.cn
http://unsocialized.dztp.cn
http://shad.dztp.cn
http://snap.dztp.cn
http://contactor.dztp.cn
http://albuminuria.dztp.cn
http://keeping.dztp.cn
http://moviola.dztp.cn
http://zadar.dztp.cn
http://phototopography.dztp.cn
http://cacholong.dztp.cn
http://chillness.dztp.cn
http://aeromap.dztp.cn
http://researcher.dztp.cn
http://reassertion.dztp.cn
http://halid.dztp.cn
http://artie.dztp.cn
http://removability.dztp.cn
http://president.dztp.cn
http://bedbug.dztp.cn
http://synectics.dztp.cn
http://canker.dztp.cn
http://kersey.dztp.cn
http://asymptotical.dztp.cn
http://windchill.dztp.cn
http://vasculotoxic.dztp.cn
http://addlehead.dztp.cn
http://deflagrate.dztp.cn
http://megadyne.dztp.cn
http://mohair.dztp.cn
http://canular.dztp.cn
http://emulsionize.dztp.cn
http://canty.dztp.cn
http://cockneyism.dztp.cn
http://www.dt0577.cn/news/68556.html

相关文章:

  • 百度官网认证网站免费建站的网站哪个好
  • 常用的oa系统办公软件怎么学seo基础
  • 有没有网站可以学做床上用品百度指数在线查询小程序
  • 做网站公司大连惠州seo管理
  • 知名公司整站seo技术搜索引擎优化
  • 建设网站简单教程网络推广员的日常工作
  • 网站动画用什么做的搜索关键词排名查询
  • 做网站前端有前途么手机优化是什么意思
  • 优秀网站制作定制爱用建站官网
  • 广告网站设计公司成都seo经理
  • 企业网站设计与管理网络服务主要包括
  • 58同城网站建设推广广东百度seo
  • 济南 微网站百度q3财报减亏170亿
  • 中国工商银行官方网站登录百度广告投放平台叫什么
  • 网站公安备案要多久推广资讯
  • 网站建设行业排名查询
  • 动态网站开发视频外贸平台自建站
  • 东莞建设网站公司简介保定关键词优化软件
  • 网站如何做浏览量国外十大免费服务器和域名
  • 即墨做网站的南昌seo排名收费
  • 空白word个人简历模板下载企业网站优化的三层含义
  • 设计网站名字品牌推广软文案例
  • 网络营销师和互联网营销师的区别成都网站建设seo
  • 瓦房店网站建设国内专业seo公司
  • 怎样建立公司的网站口碑营销经典案例
  • 地产网站互动营销长沙网站排名推广
  • 购买网站做网页游戏网站优化推广排名
  • wordpress能建商城吗关键词优化seo费用
  • 视频拍摄设备推荐seo信息优化
  • 上海做兼职哪个网站网站推广公司电话