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

国外建站数据小城镇建设官方网站

国外建站数据,小城镇建设官方网站,网络营销推广的目标与策略,可以做软件的网站有哪些功能吗✅1主页#xff1a;我的代码爱吃辣#x1f4c3;2知识讲解#xff1a;数据结构——红黑树☂️3开发环境#xff1a;Visual Studio 2022#x1f4ac;4前言#xff1a;红黑树也是一颗二叉搜索树#xff0c;其作为map#xff0c;set的底层… ✅1主页我的代码爱吃辣2知识讲解数据结构——红黑树☂️3开发环境Visual Studio 20224前言红黑树也是一颗二叉搜索树其作为mapset的底层容器具有非常好的搜索性能仅仅通过控制颜色和位置就能达到一种近似平衡的效果大大减少了旋转的次数。 目录 一.红黑树的概念 二. 红黑树的性质 三.红黑树节点及其整体的定义 四.红黑树的插入操作 五.红黑树 find 六.析构函数 七.红黑树的验证 八. 红黑树与AVL树的比较 一.红黑树的概念 红黑树是一种二叉搜索树但在每个结点上增加一个存储位表示结点的颜色可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制红黑树确保没有一条路径会比其他路径长出俩倍因而是接近平衡的。 二. 红黑树的性质 1. 每个结点不是红色就是黑色 2. 根节点是黑色的 3. 如果一个节点是红色的则它的两个孩子结点是黑色的 4. 对于每个结点从该结点到其所有后代叶结点的简单路径上均 包含相同数目的黑色结点 5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)NIL结点 思考为什么满足上面的性质红黑树就能保证其最长路径中节点个数不会超过最短路径节点个数的两倍 答案因为性质3限制了一条路径上不可能出现连续的两个红色结点。又因为性质4每条路径上黑色结点数目相同那么最短路径就一定是全是黑色结点的路径最长路径一定是红黑交错的路径因为根节点一定是黑色那么最长路径上红黑结点树一定是相等的所以最长路径最多是最短路径的两倍。 三.红黑树节点及其整体的定义 //枚举 enum Color {RED,//红色BLACK//黑色 }; templateclass K,class V struct _RBTreeNode {_RBTreeNode(pairK,V kv):_kv(kv),_col(RED),//默认红色_left(nullptr),_right(nullptr),_parent(nullptr){}pairK, V _kv; //存储数值Color _col; //颜色_RBTreeNodeK, V* _left; //左孩子_RBTreeNodeK, V* _right; //右孩子_RBTreeNodeK, V* _parent; //父亲 }; #pragma once #includeiostream using namespace std;templateclass K,class V class RBTRee {typedef _RBTreeNodeK, V Node;//结点 public:Node* find(const K key){//....}bool insert(pairK, V kv){//....}void Inorder(){//...}~RBTRee(){//...}private:Node* _root nullptr;//根节点 }; 思考在节点的定义中为什么要将节点的默认颜色给成红色的 答案新创建的结点妖色要么红色要么黑色除了颜色区别之外就是在插入时对整个树的影响不同如果插入的是黑色会影响整颗树所有路径上的黑色结点说就会不同必然违反性质4。如果插入的是红色结点仅仅是局部的影响可能会影响性质3一定不会影响性质4。 四.红黑树的插入操作 红黑树是在二叉搜索树的基础上加上其平衡限制条件因此红黑树的插入可分为两步 1. 按照二叉搜索的树规则插入新节点。 bool insert(pairK, V kv){if (_root nullptr){_root new Node(kv);_root-_col BLACK;return true;}Node* cur _root;Node* parent nullptr;while (cur){if (kv.first cur-_kv.first){parent cur;cur cur-_left;}else if (kv.first cur-_kv.first){parent cur;cur cur-_right;}else{return false;}}//找到了合适的位置cur new Node(kv);if (kv.first parent-_kv.first){parent-_left cur;}else{parent-_right cur;}cur-_parent parent;//.... } 因为性质2所以我们每一次插入数据都想根节点变成黑色。 2.检测新节点插入后红黑树的性质是否造到破坏若满足直接退出否则对红黑树进行旋转着色处理。 因为新节点的默认颜色是红色因此如果其双亲节点的颜色是黑色没有违反红黑树任何性质则不需要调整但当新插入节点的双亲节点颜色为红色时就违反了性质三不能有连在一起的红色节点此时需要对红黑树分情况来讨论 约定:cur为当前节点p为父节点g为祖父节点u为叔叔节点。 情况一 cur为红p为红g为黑u存在且为红 解决方式将 p , u 改为黑g 改为红然后把 g 当成 cur继续向上调整。 情况二: cur为红p为红g为黑u不存在/u存在且为黑 p为g的左孩子cur为p的左孩子则进行右单旋转相反p、g变色--p变黑g变红 情况三cur为红p为红g为黑u不存在/u存在且为黑 p为g的左孩子cur为p的右孩子则针对p做左单旋转 p为g的左孩子cur为p的左孩子则进行右单旋转相反p、g变色--p变黑g变红 这里的cur的也有可能是新增的结点如果是cur本身就是新增节点那么u结点就是不存在的否则违反规则 4也有可能是因为cur下面的结点变黑导致 cur 变红色。 代码 while (parent parent-_col RED){Node* grandfather parent-_parent;// g(B) g(R)// p(R) u(R) -- p(B) u(B)//c(R) c(R)if (grandfather-_left parent){Node* uncle grandfather-_right;if (uncle uncle-_col RED){parent-_col BLACK;uncle-_col BLACK;grandfather-_col RED;//继续向上调整cur grandfather;parent cur-_parent;}else //u不存在/u存在且为黑旋转变色{// g(B) p(R)// p(R) u(B) -- u(B) g(B)//c(R) u(B)if (cur parent-_left){//右单旋RotateR(grandfather);parent-_col BLACK;//cur-_col RED;grandfather-_col RED;}else{// g(B) P(B) // p(R) u(B) -- c(R) g(R)// c(R) u(B)// 左右双旋RotateL(parent);RotateR(grandfather);cur-_col BLACK;grandfather-_col RED;}break;}}else //grandfather-_right parent,与上述情况相反{Node* uncle grandfather-_left;if (uncle uncle-_col RED){parent-_col BLACK;uncle-_col BLACK;grandfather-_col RED;cur grandfather;parent cur-_parent;}else //u不存在/u存在且为黑旋转变色{if (cur parent-_right){//左单旋RotateL(grandfather);parent-_col BLACK;grandfather-_col RED;}else{// 右左双旋RotateR(parent);RotateL(grandfather);cur-_col BLACK;grandfather-_col RED;}break;}}} 旋转 void RotateL(Node* parent){Node* curR parent-_right;Node* curRL curR-_left;//调整结点并且修改其父亲结点指针parent-_right curRL;if (curRL)//可能为空{curRL-_parent parent;}//在修改子树根节点之前保存子树根节点的父亲Node* pparent parent-_parent;//修改子树根节点curR-_left parent;parent-_parent curR;//子树根节点有可能是整棵树的根节点if (pparent nullptr){_root curR;_root-_parent nullptr;}else//子树根节点不是整棵树的根节点{//还要看子树是它父亲的左孩子还是右孩子if (pparent-_left parent){pparent-_left curR;}else{pparent-_right curR;}curR-_parent pparent;}}void RotateR(Node* parent){Node* curL parent-_left;Node* curLR curL-_right;parent-_left curLR;if (curLR){curLR-_parent parent;}Node* pparent parent-_parent;curL-_right parent;parent-_parent curL;if (parent _root){_root curL;_root-_parent nullptr;}else{if (pparent-_left parent){pparent-_left curL;}else{pparent-_right curL;}curL-_parent pparent;}} 红黑树顺序插入 红黑树随机插入 五.红黑树 find 根据二叉搜索树特性去查找 Node* find(const K key){Node* cur _root;while (cur){if (key cur-_kv.first){cur cur-_left;}else if (key cur-_kv.first){cur cur-_right;}else{return cur;}}return nullptr;} 六.析构函数 后续遍历析构树 ~RBTRee(){_Destrory(_root);_root nullptr;}void _Destrory(Node* root){if (root nullptr){return;}_Destrory(root-_left);_Destrory(root-_right);delete root;} 七.红黑树的验证 红黑树的检测分为两步 检测其是否满足二叉搜索树(中序遍历是否为有序序列)检测其是否满足红黑树的性质 其中是否满足搜索树我们只要对其中序遍历是否有序即可。 完整代码 #pragma once #includeiostream using namespace std;enum Color {RED,BLACK }; templateclass K,class V struct _RBTreeNode {_RBTreeNode(pairK,V kv):_kv(kv),_col(RED),_left(nullptr),_right(nullptr),_parent(nullptr){}pairK, V _kv;Color _col;_RBTreeNodeK, V* _left;_RBTreeNodeK, V* _right;_RBTreeNodeK, V* _parent; };templateclass K,class V class RBTRee {typedef _RBTreeNodeK, V Node; public:Node* find(const K key){Node* cur _root;while (cur){if (key cur-_kv.first){cur cur-_left;}else if (key cur-_kv.first){cur cur-_right;}else{return cur;}}return nullptr;}bool insert(pairK, V kv){if (_root nullptr){_root new Node(kv);_root-_col BLACK;return true;}Node* cur _root;Node* parent nullptr;while (cur){if (kv.first cur-_kv.first){parent cur;cur cur-_left;}else if (kv.first cur-_kv.first){parent cur;cur cur-_right;}else{return false;}}cur new Node(kv);//找到了合适的位置if (kv.first parent-_kv.first){parent-_left cur;}else{parent-_right cur;}cur-_parent parent;while ( parent parent-_col RED){Node* grandfather parent-_parent;// g(B) g(R)// p(R) u(R) -- p(B) u(B)//c(R) c(R)if ( grandfather-_left parent){Node* uncle grandfather-_right;if (uncle uncle-_col RED){parent-_col BLACK;uncle-_col BLACK;grandfather-_col RED;//继续向上调整cur grandfather;parent cur-_parent;}else //u不存在/u存在且为黑旋转变色{// g(B) p(R)// p(R) u(B) -- u(B) g(B)//c(R) u(B)if (cur parent-_left){//右单旋RotateR(grandfather);parent-_col BLACK;//cur-_col RED;grandfather-_col RED;}else{// g(B) P(B) // p(R) u(B) -- c(R) g(R)// c(R) u(B)// 左右双旋RotateL(parent);RotateR(grandfather);cur-_col BLACK;grandfather-_col RED;}break;}}else //grandfather-_right parent,与上述情况相反{Node* uncle grandfather-_left;if (uncle uncle-_col RED){parent-_col BLACK;uncle-_col BLACK;grandfather-_col RED;cur grandfather;parent cur-_parent;}else //u不存在/u存在且为黑旋转变色{if (cur parent-_right){//左单旋RotateL(grandfather);parent-_col BLACK;grandfather-_col RED;}else{// 右左双旋RotateR(parent);RotateL(grandfather);cur-_col BLACK;grandfather-_col RED;}break;}}}_root-_col BLACK;return true;}void Inorder(vectorK v){_inorder(_root,v);cout endl;}~RBTRee(){_Destrory(_root);_root nullptr;}private:void _Destrory(Node* root){if (root nullptr){return;}_Destrory(root-_left);_Destrory(root-_right);delete root;}void _inorder(Node* root, vectorK v){if (root nullptr){return;}_inorder(root-_left,v);v.push_back(root-_kv.first);_inorder(root-_right,v);}void RotateL(Node* parent){Node* curR parent-_right;Node* curRL curR-_left;//调整结点并且修改其父亲结点指针parent-_right curRL;if (curRL)//可能为空{curRL-_parent parent;}//在修改子树根节点之前保存子树根节点的父亲Node* pparent parent-_parent;//修改子树根节点curR-_left parent;parent-_parent curR;//子树根节点有可能是整棵树的根节点if (pparent nullptr){_root curR;_root-_parent nullptr;}else//子树根节点不是整棵树的根节点{//还要看子树是它父亲的左孩子还是右孩子if (pparent-_left parent){pparent-_left curR;}else{pparent-_right curR;}curR-_parent pparent;}}void RotateR(Node* parent){Node* curL parent-_left;Node* curLR curL-_right;parent-_left curLR;if (curLR){curLR-_parent parent;}Node* pparent parent-_parent;curL-_right parent;parent-_parent curL;if (parent _root){_root curL;_root-_parent nullptr;}else{if (pparent-_left parent){pparent-_left curL;}else{pparent-_right curL;}curL-_parent pparent;}}Node* _root nullptr;}; //传参时benchmark是-1代表还没有基准值当走完第一条路径时//将第一条路径的黑色节点数作为基准值后续路径走到null时就与基准值比较。//blacknum记录路径上的黑色节点数bool _isRBTree(Node* root, int blacknum, int benchmark){if (root nullptr){if (benchmark -1){benchmark blacknum;}else{if (blacknum ! benchmark){cout black Node ! endl;return false;}}return true;}if (root-_col BLACK){blacknum;}//判断时候出现两个连续的红色结点if (root-_col RED root-_parent root-_parent-_col RED){cout red connect endl;return false;}return _isRBTree(root-_left, blacknum, benchmark) _isRBTree(root-_right, blacknum, benchmark);} main.cpp #includevector #includecassert #includeRB_Tree.hppint main() {RBTReeint, int rb;int i 100000;while(i--){int num rand() i;rb.insert(make_pair(num,num));}vectorint v;rb.Inorder(v);for (int i 0; i v.size() - 1; i){if (v[i] v[i 1]){assert(0);}}cout rb.isRBTree() endl;return 0; } 八. 红黑树与AVL树的比较 红黑树和AVL树都是高效的平衡二叉树增删改查的时间复杂度都是O()红黑树不追 求绝对平衡其只需保证最长路径不超过最短路径的2倍相对而言降低了插入和旋转的次数 所以在经常进行增删的结构中性能比AVL树更优而且红黑树实现比较简单所以实际运用中红 黑树更多。
http://www.zqtcl.cn/news/691475/

相关文章:

  • 做淘客网站怎么样济南软件公司排名
  • 企业网站优化兴田德润怎么样网站建设建设公司资质要求
  • 如何把网站做跳转浏览器链接地址wordpress 离线更新
  • 乌海学校网站建设wordpress默认主题下载
  • 海兴县做网站如何选网站建设公司
  • asp网站设为首页代码孝仙洪高速公路建设指挥部网站
  • 浦东新区网站开发人才网站建设策划书
  • 网站做flash好不好免费微信公众号素材网
  • 开发网站嵌入广告汕头电商网站建设
  • 电脑做科目一网站购物网站怎么创建
  • c2c网站建设公司wordpress被公众号干掉
  • wordpress托管建站网站页面布局和样式设计
  • 建站平台江苏省建设监理协会网站
  • 安徽网站开发培训价格百度seo排名公司
  • 青海网站建设费用oa系统和erp系统区别
  • 个人做网站的注意事项网站开发工程师6
  • 镇江百度网站建设北京网站开发价格
  • 大岭山镇仿做网站推广计划表格
  • 网站备案地址不是我的地址怎么办建设银行网站查询业务收费吗
  • 电商网站设计内容网站编辑及seo招聘
  • 用什么网站开发浙江省住房和建设厅网站
  • 站长工具seo优化建议微信小程序线上商城怎么申请
  • 建筑网站开发设计做网站的公司msgg
  • 设计师个人网站模板网站的尾页要怎么做
  • 营销型网站建设风格设定包括哪些方面wordpress企业魔板
  • 怎样做淘客网站做绿色产品的网站
  • 关于网站建设的通知wordpress点注册后一直不出来
  • 科技公司网站设计方案开发公司绩效考核
  • 深圳网站建设推进旗县政务网站建设工作方案
  • 南宁 网站建设网站集约建设