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

div+css网站模版下载推广普通话的意义50字

div+css网站模版下载,推广普通话的意义50字,长沙营销型网站建设,wordpress免插件cdn加速目录 一、红黑树的概念 二、红黑树的定义 三、红黑树的实现 一、红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或者Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#…

目录

一、红黑树的概念

二、红黑树的定义

三、红黑树的实现

一、红黑树的概念

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

1.1红黑树的性质

1.每个结点不是红色就是黑色

2.根节点是黑色的

3.如果一个节点是红色的,则它的两个孩子结点是黑色的(不能出现连续的红色节点,父子节点:黑+黑/黑+红)

4.对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点(每条路径都包含相同数量的黑色节点)

5.每个叶子结点都是黑色的(此处的叶子结点指的是空结点)->方便数路径

注:路径是从根节点走到空

像这样的红黑树看似只有四条路径,实际上有八条路径,原因就是算上了空结点如下图 

 这也是为了更好地判断红黑树,避免混淆

像这个就不是红黑树,原因就是分出来红色那条线也算一条路径 

 那为什么能保证最长路径是最短路径的二倍呢?

最短路径:全黑

最长路径:一黑一红

 假设每条路径都有N个黑色节点

每条路径的节点数量在N-2N之间

二、红黑树的定义

enum Color
{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;Color _col;RBTreenode(const pair<K, V>& kv):_left(nullptr), _right(nullptr), _parent(nullptr), _kv(kv), _col(Red){}
};

2.1插入 

大致的插入代码上和AVL数差不多,具体的大家可以看一下我的AVL搜索树的这篇文章

https://mpbeta.csdn.net/mp_blog/creation/editor/147169928https://mpbeta.csdn.net/mp_blog/creation/editor/147169928那我们 再想一下新增节点是红色的还是黑色的

如果我们在一条路径上新增的是黑色节点,那么势必会影响到所有的路径,因为每条路径的黑色节点是固定的,如果你新增的是红色节点,只会影响父亲,我们只需要根据规则灵活改变就行了 

那我们选择了新增节点是红色的以后,分以下两种情况来讨论

1.新增节点父亲是黑色的,那么插入结束,不需要处理

2.新增节点父亲是红色的,需要处理(变色)/(旋转+变色)

我们看新增一个红色节点,如果父亲是红色的,那违反规则我们就把它变黑色,但是这条路径多了一个黑色节点,我们要减少一个黑色节点,把6变红,但是6的左边少了一个黑色节点,所有我们把5变黑,这只是最简单的一种情况

5是新增节点,如果我们还按上面的方法来把6变黑,把4变红,但是4的左没有节点了,就无法达到黑色节点平衡,这时候我们就要用到AVL树里面的双旋,旋转+变色

我们 这里先双旋完,看就符合我们上面的步骤了

结论:关键看的是叔叔

cur为当前节点,f为父节点,g为祖父节点,u为叔叔节点

情况一:cur为红,f为红,g为黑,u存在且为红

 解决方式:将f,u改为黑,g改为红,然后把g当成cur,继续向上调整

如果g是根,那把g变为黑色没问题;

如果g不是根,如果不把g变黑就会凭空多出一个黑色节点,所以我们变红,但是插入之前g是黑,我们继续要向上看,如果g的上面是黑那不用调整,如果是红还要继续向上调整

我们再把这个图拿出来细分一下

 

a,b是一个红节点 ,新增插入一个红节点,插入在a,b孩子热议位置,都引发变色+向上处理

像在这里的话,如果我们在b位置插入,插入节点就是cur,b就是f,a就是u,g就是之前的cur

所以说cur不一定是新增,也有可能是a,b的爷爷

那有多少种情况呢

cde形状组合:4*4*4

插入位置:4个位置

合计组合:256种情况,如果每条路径有两个黑色节点,那将是指数级增长,所以情况是很多的,才引申出来的抽象图

情况二:cur为红,f为红,g为黑,u不存在/u存在且为黑

 

 

 如果u存在且为黑

 如果我们要继续更改父亲变成黑色的话,黑色节点就无法控制了,就是你把f变黑,凭空多出一个黑色节点,用g变红来抵消,但是u的路径上就少了一个黑色节点,但是u本身也是黑色节点无法改变,这时候我们也仔细看一下最长路径已经超过最短路径的2倍了,所以我们要旋转+变色

 

解决方案:

f为g的左孩子,cur为f的左孩子,则针对f进行右单旋;

f为g的右孩子,cur为f的右孩子,则针对f进行左单旋

f、g变色--f变黑,g变红

那上面这种我们能不能换一种方案

不好,因为它不是终结态,f是红我们还要继续向上更新判断,f是黑我们就不用继续在向上更新了

 情况三:cur为红,f为红,g为黑,u不存在且为黑

这种情况其实和上面是类似的,无非就是旋转的问题而已

解决方案:

f为g的左孩子,cur为f的右孩子,则针对f进行左单旋;

f为g的右孩子,cur为f的左孩子,则针对f进行右单旋

就转换为了情况2

最终呈现的是

u不存在,abcde都是空

u存在且为黑,abc都是一个黑色节点的红黑树,de是空或者红色节点

三、红黑树的实现

3.1旋转

void RoLeft(Node * parent)
{Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;SubR->_left = parent;if (SubRL)SubRL->_parent = parent;Node* parentParent = parent->_parent;parent->_parent = SubR;if (_root == parent){_root = SubR;SubR->_parent = nullptr;}else {if (parentParent->_left == parent){parentParent->_left = SubR;}else{parentParent->_right = SubR;}SubR->_parent = parentParent;}
}
void RoRight(Node * parent)
{Node* SubL = parent->_left;Node* SubLR = SubL->_right;SubL->_right = parent;parent->_left = SubLR;if (SubLR)SubLR->_parent = parent;Node* parentParent = parent->_parent;parent->_parent = SubL;if (_root == parent){_root = SubL;SubL->_parent = nullptr;}else{if (parentParent->_left == parent){parentParent->_left = SubL;}else{parentParent->_right = SubL;}SubL->_parent = parentParent;}
}

3.2插入

	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;cur->_parent = parent;}else{parent->_left = cur;cur->_parent = parent;}while (parent&&parent->_col == Red){//      g//    p  u//  cNode* grandfather = parent->_parent;if(grandfather->_left==parent){Node* uncle = grandfather->_right;//叔叔存在且为红if (uncle && uncle->_col == Red){parent->_col = uncle->_col = Black;grandfather->_col = Red;cur = grandfather;parent = grandfather->_parent;}else{if (parent->_left == cur){//叔叔不存在或者叔叔存在且为黑RoRight(grandfather);parent->_col = Black;grandfather->_col = Red;}	//      g//    p  u//  celse{//叔叔不存在或者叔叔存在且为黑RoLeft(parent);RoRight(grandfather);cur->_col = Black;grandfather->_col = Red;}break;}}//      g//    u  p//       celse{Node* uncle = grandfather->_left;if (uncle && uncle->_col == Red){parent->_col = uncle->_col = Black;grandfather->_col = Red;cur = grandfather;parent = cur->_parent;}else {//      g//    u  p//       cif (parent->_right == cur){RoLeft(grandfather);grandfather->_col = Red;parent->_col = Black;}else{RoRight(parent);RoLeft(grandfather);grandfather->_col = Red;cur->_col = Black;}break;}}}_root->_col = Black;return true;}
void InOrder()
{_InOrder(_root);cout << endl;
}void _InOrder(Node* root)
{if (root == nullptr)return;_InOrder(root->_left);cout << root->_kv.first << " ";_InOrder(root->_right);
}

每一种情况我都有在上面做一点小标记,大家把我上面红黑树定义里面的情况都画出来,对照着写代码就可以了

3.3测试

int main()
{const int N = 30;vector<int> v;v.reserve(N);srand(time(0));for (size_t i = 0; i < N; i++){v.push_back(rand());}RBtree<int, int> t;for (auto e : v){t.Insert(make_pair(e, e));}t.InOrder();return 0;
}

我在这里放随机数来测定,如果随机数测定成功了,那么静态数据也可以成功

还是和AVL树一样这里我们只能判断它是搜索树,不能判断它是红黑树

所以我们还要针对红黑树的规则来针对它写代码来测试它 

针对规则三我们直接检查其实不好检查,因为孩子节点的情况太多了,两个孩子可以为空,为红等等 

针对规则4我们可以考虑传值而不是传引用

我们使用传值的时候比如说2是1到1变2,但是返回上去到2的右还是1这样我们就能验证每条路径的黑色节点数量,那我们是否要记录下来呢,可以记录,把他们都放到一个数组vector里面去,或者我们可以更好地给出一个参考值,判断一下和这个参考值是否相等就行了 

	bool IsBalance(){return _IsBalance(_root);}bool Check(Node* root,int blacknum,const int Referencevalue){if (root == nullptr){if (blacknum != Referencevalue){cout << "存在黑色节点数量不相等的路径" << endl;}return true;}if (root->_col == Red&&root->_parent->_col==Red){cout << "有连续的红色节点" << endl;return false;}if (root->_col == Black){++blacknum;}return Check(root->_left, blacknum, Referencevalue) && Check(root->_right, blacknum, Referencevalue);}bool _IsBalance(Node* root){if (root == nullptr)return false;if (root->_col == Red)return false;int blacknum = 0;int Referencevalue = 0;Node* cur = root;while (cur){if (cur->_col == Black)Referencevalue++;cur = cur->_left;}return Check(root, blacknum, Referencevalue);}

 

红黑树就写到这里了,接下来进入更难的封装,红黑树有了AVL树旋转做基础和铺垫学起来也会不那么复杂

http://www.dtcms.com/wzjs/72619.html

相关文章:

  • 简述网站建设的标准关键词查询
  • 个人网站制作dw百度关键词怎么刷上去
  • 河南网站建站系统哪家好枣庄网站seo
  • 中小型网站建设价格手机网站怎么优化
  • 网站服务器租赁你的知识宝库免费二级域名查询网站
  • 黄金做空网站百度竞价广告的位置
  • 济南网站建设和维护seo关键词优化方法
  • 用discuz做商城网站如何制作微信小程序店铺
  • 莆田有交做外贸网站的没sem推广什么意思
  • linux 什么做网站好网站推广是什么意思
  • 用手机建网站外链发布
  • 张家港网站建设培训班企业网络营销青岛
  • 网站专业销售团队介绍网站建设黄页免费观看
  • 南京网络科技网站建设广西网络推广公司
  • 移动端网站设计规范网络推广有哪些方法
  • 深圳做网站建设公司搜索推广是什么意思
  • 网站建设成本百度宣传推广
  • 电子商务网站建设的毕业论文竞价推广什么意思
  • 网页设计实验报告问题讨论进一步优化
  • 临沂企业建站程序seo中心
  • 手机能用的网站安装百度一下
  • 成营销型网站制作百度首页排名怎么做到
  • 怎么样创建一个网站最新网站推广方法
  • 网站搜索不出来新手做seo怎么做
  • 快速制作网站的方法百度关键词排名推广话术
  • 河北省住房和城乡建设厅官方网站网络营销的培训课程
  • 东莞餐饮网站建设seo如何优化一个网站
  • 怎样做企业学校网站乐清网站建设
  • 济南网站建设培训班chrome手机版
  • 网站是谁做的网络营销站点推广的方法