网站的开发公司倒闭对网站使用seosem顾问

web/2025/10/5 20:13:47/文章来源:
网站的开发公司倒闭对网站使用,seosem顾问,网站怎么做别名,免费做网站刮刮卡红黑树 引言红黑树的介绍实现结点类insert搜索插入位置插入调整当parent为gparent的左子结点当parent为gparent的右子结点 参考源码测试红黑树是否合格总结 引言 在上一篇文章中我们认识了高度平衡的平衡二叉树AVL树#xff1a;戳我看AVL树详解哦 #xff08;关于旋转调整的… 红黑树 引言红黑树的介绍实现结点类insert搜索插入位置插入调整当parent为gparent的左子结点当parent为gparent的右子结点 参考源码测试红黑树是否合格总结 引言 在上一篇文章中我们认识了高度平衡的平衡二叉树AVL树戳我看AVL树详解哦 关于旋转调整的部分在AVL树的时候已经详细介绍过了如果大家对旋转调平衡的部分有疑惑的话请移步至AVL树的详解 由于AVL树的高度平衡其平均搜索时间复杂度几乎可以达到严格的O(logN)。同样也因为平衡的程度很高在维护平衡上时间的花费对于搜索上时间的提升是得不偿失的。 大多数情况下我们并不需要很高的平衡程度只需要达成一种接近平衡的状态搜索的平均时间复杂度基本达到O(logN)即可。 红黑树就是这样的一种结构它的最高子树的高度小于等于最低子树的二倍。通过减少调平衡时的时间成本来提高效率 红黑树的介绍 红黑树是平衡二叉树的一种他在满足二叉搜索树特性的基础上给每个结点增加了一个颜色属性包括Red与Black并要求从根节点到一个叶子结点形成的任意一条路径中通过对结点颜色的限制规则没有任何一条路径回比其他的路径长一倍 红黑圣诞树 对于红黑树结点颜色的限制规则如下 每个结点的颜色只有红色或黑色两种根结点的颜色一定是黑色的如果某一个结点的颜色是红色的它的两个孩子结点的颜色一定是黑色即不存在两个连续的红色结点对于任一结点到叶子结点的任一路径上包含的黑色结点的数量一定相等叶子结点一定是黑色的这里的叶子结点直最后的nullptr 当满足上面的所有规则时根节点到叶子结点的任一路径就都不可能比其他路径长一倍。由于不存在连续的红色结点所以当黑色结点的数量 n 一定时最长路径的长度为2 * n最短路径的长度为 n 所以不可能相差一倍以上。这样就达成了一种相对平衡的状态并不需要经常去旋转调平了。 实现 红黑树的实现在之前的二叉搜索树上增加了结点的颜色以及对于结点的颜色调整的部分 在本篇文章中依旧实现 K-V的模式 的树 并且以非递归实现insert 为防止命名冲突将实现放在我们的命名空间qqq中 结点的颜色我们使用 枚举常量enum Color 来表示 RBTree是一个类模板有两个模板参数即K与V表示其中存储的索引类型与值类型 成员变量类型为Node*由结点类RBTreeNode重命名表示根结点的指针 //基本的代码结构 namespace qqq {enum Color //枚举常量表示颜色{RED,BLUCK};templateclass K, class Vstruct RBTreeNode //结点类{};templateclass K, class Vclass RBTree //红黑树{typedef RBTreeNodeK, V Node;public:bool insert(const pairK, V kv){}protected:Node* _root nullptr;}; }结点类 首先对红黑树的结点进行实现 RBTreeNode是也一个类模板 两个模板参数同样为K与V表示索引与值的类型 在结点中储存数据的结构为pair其中first为K类型second为V类型 成员变量包括结点中的数据 _kv 指向父亲结点的指针 _parent 指向左右孩子结点的指针 _left 与 _right 表示结点颜色的枚举常量 _col templateclass K, class V struct RBTreeNode //结点类 {pairK, V _kv;RBTreeNodeK, V* _parent;RBTreeNodeK, V* _left;RBTreeNodeK, V* _right;Color _col; };结点类的构造函数 我们需要实现一个默认构造函数 参数类型为const pairK, V缺省值为一个pairK, V的匿名对象 对于父子结点的指针在初始化列表中初始化为nullptr即可 对于结点的颜色在初始化列表中初始化为RED要保证每条路上黑色结点的个数相等就必须初始化为红色 RBTreeNode(const pairK, V kv pairK, V()): _kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _col(RED){}insert 红黑树的insert分为两个部分即搜索并插入以及调整使其满足红黑树的性质 搜索插入位置 与二叉搜索树类似搜索并插入时首先用要插入的pair对象创建一个新结点newnode与此同时使用结点指针 cur来记录当前位置 parent来记录cur的父结点便于后面插入然后 while循环向下查找 插入的位置当newnode小于cur的元素时向左查找当newnode大于cur的元素时向右查找相等时即该元素已经存在返回false当cur为nullptr时表示找到了插入的位置循环终止 // 部分代码搜索插入位置 // Node* newnode new Node(kv); Node* parent nullptr; Node* cur _root;while (cur ! nullptr) //搜索 {if (newnode-_kv.first cur-_kv.first){parent cur;cur parent-_right;}else if (newnode-_kv.first cur-_kv.first){parent cur;cur parent-_left;}else //相等即插入失败{return false;} }插入 将newnode插入红黑树即将newnode与parent链接这时就需要判断parent是否为空当parent为空时即cur就是根节点_root即newnode是这棵红黑树中的第一个结点将 其赋值给_root 即可当parent不为空时 还需要判断cur位于parent的左边还是右边然后再插入 // 局部代码插入newnode // if (parent nullptr) //插入 {_root newnode; } else if (newnode-_kv.first parent-_kv.first) {parent-_left newnode;newnode-_parent parent;cur newnode; } else {parent-_right newnode;newnode-_parent parent;cur newnode; }调整 在完成插入后首先需要判断的是parent指针的状态 当parent为空时表明当前结点为根结点将其颜色改为BLACK即可调整完毕当parent指向结点的颜色为BLACK 时如果是在刚插入时新插入的结点颜色为RED不会影响该路径的黑色节点个数所以不再需要调整。如果是在向上调整的过程中parent指向的结点为BLACK也意味着整棵树调整结束了这一点在后面的调整部分会详细介绍除了上面不用调整的两种情况外其余的情况即 parent指向的结点存在且为RED 的情况就需要进行调整了。调整是自下而上的循环向上调整直到 parent为空或parent指向的结点为BLACK时循环结束调整完成 // 部分代码自下而上调整的循环框架 // while (parent ! nullptr parent-_col ! BLUCK) {}开始调整时首先对parent为gparentcur的祖父结点的左子结点还是右子结点做一分类讨论当parent不为黑时由于根结点必须为黑所以parent不是根结点所以gparent一定存在 当parent为gparent的左子结点 当parent为gparent的左子结点时我们首先要考察cur叔叔结点的情况 当cur的叔叔结点为RED 时不需要进行旋转调整只需要将gparent指向结点设置为RED将parent和cur的叔叔结点全部设置为BLACK即可 由于在调整完颜色后gparent指向结点颜色就为RED了这时如果gparent父结点的颜色正好为红就出现了连续的两个红色结点。所以需要将cur向上移动两个结点再对其parent指向的结点继续进行判断 当cur的叔叔结点为BLACK或不存在时就需要进行旋转调整了 旋转的逻辑与之前AVL树类似当cur位于parent的左边时即左左——单次右旋 当cur位于parent的右边时即左右——左右双旋 旋转调整后将gparent指向结点设置为RED将子树顶部的结点设置为BLACK 即可parent指向的结点或cur指向的结点 经过旋转后的红黑树子树顶部的颜色一定为黑色再向上也就不会存在两个连续的红色结点的问题了所以旋转之后直接终止循环即可。 需要注意的是叔叔是黑色结点的情况一定是出现在调整过程中发生的当叔叔结点为黑色时cur下的路径中一定存在着与gparent右子树中黑色结点相同个数的黑色结点parent下的路径中同样也存在着相同数目的黑色结点这样在旋转调平衡后这棵子树中的所有路径中的黑色结点数目与之前是不变的。 //部分代码当parent为gparent左子结点的情况 if (parent gparent-_left) {if (gparent-_right nullptr || gparent-_right-_col BLUCK) //1.叔叔结点不存在或为黑需要旋转并调色{if (cur parent-_left)//左左-单次右旋{RotateR(gparent);parent-_col BLUCK;gparent-_col RED;}else//左右-左旋右旋{RotateL(parent);RotateR(gparent);cur-_col BLUCK;gparent-_col RED;}break; //通过旋转调整后该子树的根结点一定是黑所以可以直接结束循环}else if (gparent-_right-_col RED) //2.叔叔结点为红通过调色即可实现红黑树{//调色parent-_col BLUCK;gparent-_right-_col BLUCK;gparent-_col RED;//继续向上cur gparent;parent cur-_parent;}else{assert(0);} }当parent为gparent的右子结点 当parent为gparent的右子结点时与上面的情况一致只是左右对调了所以这里只给出图示与代码如果在这种情况下遇到了问题希望你在上面的情况中能够找到答案 叔叔结点为RED仅调整颜色 叔叔结点为BLACK或不存在左单旋或右左双旋: 左单旋 右左双旋 旋转后调整颜色 旋转后子树顶部的结点一定为BLACK所以直接break即可。 //部分代码当parent为gparent右子结点的情况 // else //parent gparent-_right {if (gparent-_left nullptr || gparent-_left-_col BLUCK) //1.叔叔结点不存在或为黑需要旋转并调色{if (cur parent-_right)//右右-单次左旋{RotateL(gparent);parent-_col BLUCK;gparent-_col RED;}else//右左-右旋左旋{RotateR(parent);RotateL(gparent);cur-_col BLUCK;gparent-_col RED;}break; //通过旋转调整后该子树的根结点一定是黑所以可以直接结束循环}else if (gparent-_left-_col RED) //2.叔叔结点为红通过调色即可实现红黑树{//调色parent-_col BLUCK;gparent-_left-_col BLUCK;gparent-_col RED;//继续向上cur gparent;parent cur-_parent;}else{assert(0);} }在while循环调整结束之后再将根结点_root的颜色改为BLACK统一做处理insert的整体代码在这里就不做展示了大家跳转至参考源码部分查看即可。 参考源码 namespace qqq {enum Color //枚举常量表示颜色{RED,BLUCK};templateclass K, class Vstruct RBTreeNode //结点类{pairK, V _kv;RBTreeNodeK, V* _parent;RBTreeNodeK, V* _left;RBTreeNodeK, V* _right;Color _col;RBTreeNode(const pairK, V kv pairK, V()): _kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _col(RED){}};templateclass K, class Vclass RBTree //红黑树{typedef RBTreeNodeK, V Node;public:bool insert(const pairK, V kv){ //先插入Node* newnode new Node(kv);Node* parent nullptr;Node* cur _root;while (cur ! nullptr) //搜索{if (newnode-_kv.first cur-_kv.first){parent cur;cur parent-_right;}else if (newnode-_kv.first cur-_kv.first){parent cur;cur parent-_left;}else //相等即插入失败{return false;}}if (parent nullptr) //插入{_root newnode;}else if (newnode-_kv.first parent-_kv.first){parent-_left newnode;newnode-_parent parent;cur newnode;}else{parent-_right newnode;newnode-_parent parent;cur newnode;}//调整颜色以及旋转使满足红黑树while (parent ! nullptr parent-_col ! BLUCK) //当parent不为黑时由于根结点必须为黑所以parent不是根结点所以gparent一定存在{Node* gparent parent-_parent;if (parent gparent-_left) {if (gparent-_right nullptr || gparent-_right-_col BLUCK) //1.叔叔结点不存在或为黑需要旋转并调色{if (cur parent-_left)//左左-单次右旋{RotateR(gparent);parent-_col BLUCK;gparent-_col RED;}else//左右-左旋右旋{RotateL(parent);RotateR(gparent);cur-_col BLUCK;gparent-_col RED;}break; //通过旋转调整后该子树的根结点一定是黑所以可以直接结束循环}else if (gparent-_right-_col RED) //2.叔叔结点为红通过调色即可实现红黑树{//调色parent-_col BLUCK;gparent-_right-_col BLUCK;gparent-_col RED;//继续向上cur gparent;parent cur-_parent;}else{assert(0);}}else{if (gparent-_left nullptr || gparent-_left-_col BLUCK) //1.叔叔结点不存在或为黑需要旋转并调色{if (cur parent-_right)//右右-单次左旋{RotateL(gparent);parent-_col BLUCK;gparent-_col RED;}else//右左-右旋左旋{RotateR(parent);RotateL(gparent);cur-_col BLUCK;gparent-_col RED;}break; //通过旋转调整后该子树的根结点一定是黑所以可以直接结束循环}else if (gparent-_left-_col RED) //2.叔叔结点为红通过调色即可实现红黑树{//调色parent-_col BLUCK;gparent-_left-_col BLUCK;gparent-_col RED;//继续向上cur gparent;parent cur-_parent;}else{assert(0);}}}_root-_col BLUCK;return true;}void RotateL(Node* parent){Node* gparent parent-_parent;Node* cur parent-_right;Node* curleft cur-_left;parent-_right curleft;if (curleft ! nullptr){curleft-_parent parent;}cur-_left parent;parent-_parent cur;cur-_parent gparent;if (gparent nullptr){_root cur;}else{if (cur-_kv.first gparent-_kv.first){gparent-_left cur;}else{gparent-_right cur;}}}void RotateR(Node* parent){Node* gparent parent-_parent;Node* cur parent-_left;Node* curright cur-_right;parent-_left curright;if (curright ! nullptr){curright-_parent parent;}cur-_right parent;parent-_parent cur;cur-_parent gparent;if (gparent nullptr){_root cur;}else{if (cur-_kv.first gparent-_kv.first){gparent-_left cur;}else{gparent-_right cur;}}}bool isRBTree(){return isRBTree(_root);}protected:Node* _root nullptr;bool checkColor(Node* root, int countBluck, int baseBluck) //计算黑结点数量与红结点连续是否满足条件{if (root nullptr){if (baseBluck countBluck){return true;}return false;}if (root-_col RED root-_parent ! nullptr root-_parent-_col RED){return false;}if (root-_col BLUCK){countBluck;}return checkColor(root-_left, countBluck, baseBluck) checkColor(root-_right, countBluck, baseBluck);}bool isRBTree(Node* root){if (root nullptr)return true;if (root-_col RED)return false;//先计算一条路径中的黑色结点数量int baseBluck 0;Node* cur root;while (cur ! nullptr){if (cur-_col BLUCK){baseBluck;}cur cur-_right;}return checkColor(root, 0, baseBluck);}}; }测试红黑树是否合格 在写完红黑树的insert之后我们可以再编写一个测试模块来测试一棵树是否满足红黑树的特性 我们其实只需要判断两点即可 任一路径上的黑色结点个数是否相等是否存在连续的两个红色结点。 我们使用递归的方式来判断 判断任一路径上的黑色结点个数是否相等时必须要先计算某条路径上的黑色结点个数可以通过 while循环计算最右侧一条路径上的黑色结点个数。将cur从_root开始一直向右子节点遍历即可当cur为空时即该路径结束终止循环。 然后使用checkColor函数参数为当前结点指针Node*计算中的当前路径黑色结点个数int以及先前计算的最外层黑色结点个数int 递归计算每条路径上的黑色结点个数顺便判断是否存在连续的红色结点。 在递归过程中 当_root为空时即当前路径已经结束判断countBluck与baseBlack的值是否相等若相等返回true否则返回false 若当前结点为红色则判断其父结点是否为红色是就返回false 若当前结点为黑色countBluck加1并继续向左右子结点递归返回左子结点的结果右子结点的结果: 测试红黑树是否合格的代码这里就不赘述了大家可以在参考源码部分查找。这里来展示一下测试结果 namespace qqq {void testfunc(){const int N 10000000;vectorint v;v.reserve(N);srand(time(0));for (size_t i 0; i N; i){v.push_back(i);}RBTreeint, int rbt;for (auto e : v){rbt.insert(make_pair(e, e));cout insert: e - rbt.isRBTree() endl;}cout rbt.isRBTree() endl;} }int main() {qqq::testfunc();return 0; }因为这段测试代码中存在大量I/O所以运行速度很慢大家可以将cout注释掉只打印最后的结果。 总结 到此关于红黑树的知识就介绍完了 在接下来的文章中将会对红黑树进行封装即map与set尽情期待哦 如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题欢迎大家在评论区提出 如果本文对你有帮助希望一键三连哦 希望与大家共同进步哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站改版后seo该怎么做江苏网站建设yijuce

目录 1.数据流图 2.变换型设计和事务型设计 3.程序流程图 4.NS图和PAD图: 5.UML图 1.用例图 2.类图 3.顺序图 4.协作图 本文为个人复习资料,包含个人复习思路,多引用,也想和大家分享一下,希望大家不要介意~ …

手机上网站用建设工具h5制作平台排名

接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识。 Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的Mono运行时还未升级。 新编译器仍针对C# 4,是旧的编译器也支持的版本。 …

承德网站建设流程网站流量如何来

如何通过adb获取root权限(安卓电视盒和智能电视通用)?Android 系统rom里面最主要的就3个文件:boot.img、system.img、userdata.img其中boot.img 存放着内核以及Android系统的配置信息,比如android系统各文件夹的读写权限,adb 的权限。所以如…

银川市做网站的公司seo百家论坛

JAVA数组与类的定义-java实验报告JAVA数组与类的定义-java实验报告、实验目的与要求1、 熟悉Java类、对象和方法的一般操作练习等。2、 熟悉数组等的定义和使用。二、实验内容及步骤(包括源程序和运行结果截图)1. 编写Java小应用程序,程序中自定义一个方法&#xff…

网站建设是怎么建的wordpress自动播放音乐

一、安装node.js 1、在官网中安装nodejs最新版本。地址:https://nodejs.org/en/download/,根据自己环境,进行下载安装。 2、安装完成后,进行nodejs版本及npm版本查看。 打开cmd命令行,输入 node -v 和 npm -v&#…

网站开发工具 哪个好网站域名续费怎么续费

用java语言可以实现人民币小写转换为大写吗?如何实现呢?下面常见的用java实现人民币小写变大写的方法可以说是最精简的了,希望大家可以学习下。这里介绍一个通过取余的办法来实现将人民币小写转换为大写形式,个人认为比TTS上面的答…

安徽常青建设集团网站网站后台上传文件

在ROS导航中,激光雷达(Laser Scanner)通常被用于感知机器人周围的环境,进行障碍物检测和建图,以支持导航。下面是激光雷达的详细介绍以及一个示例: 激光雷达简介: 激光雷达是一种传感器&#…

已认证网站服务费怎么做网页托管平台

来源 计算机器人 transformation matrix 相关内容时,对于关节角度进行离散,循环计算很慢,随着角度划分越来越细,怎么提高速度是一个问题。 最优解决方法 fun_handle matlabFunction(T_t2b_RPY_tmp);T_t2b_RPY_tmp是 transform…

中山市规划建设局网站seo排名赚能赚钱吗

VR虚拟现实原型制作 利用VR虚拟现实软件进行原型制作可以用于增强原型测试期间的沉浸感,减少产品设计迭代次数,并将与产品原型制作相关的成本降低40-65%。 VR虚拟现实原型制作市场规模 用于原型制作的虚拟现实 (VR) 市场在 2017 年估计为 2.104 亿美元…

网站开启速度变慢了腾讯企业邮箱如何注册

首先我们做技术,尤其是java开发人员,应该对Spring、SpringBoot、SpringCloud 三个家伙一点不陌生。 结合发展史Spring出现的最早,后面为了可以让开发人员偷懒,简化配置,就是约定犹于配置或者说大于,进而出…

手机微网站怎么做的惠州做网站

StorageFile.ContentType 属性,是 string 类型,用来表示文件内容的 MIME 类型。例如,音乐文件可能有 "audio/mpeg" MIME 类型。(MSDN) MIME 类型的定义可以下面的链接找到: MIME Types - http://blogs.msdn.com/b/jaime…

阿里云网站备案要多久怎么做网站关键字

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 定时任务模块APScheduler 一、安装及基本概念 1.1、APScheduler的安装 1.2、涉及概念 1.3、APScheduler的工作流程​编辑 二、配置调度器 …

网站备案 公司网站建设和优化排名

接上一篇补充 git config --global user.name " " git config --global user.email 邮箱地址 配置用户名和邮箱 git commit 使其处于交互区,没有使用 -m,默认用vim 来编辑和提交信息 输入要提交的内容,然后按ESC建回到命令…

微网站功能列表彩票网站开发的

继续是机器学习课程的笔记,这节课会介绍逻辑回归。 分类问题 这节课会介绍的是分类问题,其结果是离散值。分类问题的例子有判断电子邮件是否是垃圾邮件;判断肿瘤是良性还是恶性;判断一次金融交易是否是欺诈等等。 首先从二元的…

哈尔滨大型网站建设电话策划运营

ThreeJS的动画系列分为:基础动画、相机控制、变形动画、用骨骼和蒙皮制作动画以及使用外部模型创建动画。用骨骼和蒙皮制作动画用骨骼来做动画时,移动一下骨骼,Three.js必须决定如何相应地迁移附着在骨骼上的皮肤,一起来看吧~~~举…

小程序推广模式和营销方案成都seo论坛

重置MYSQL密码后,Navicat连接报错:2003 - Can‘t connect to MySQL server on ‘127.0.0.1‘ (61 “Connection refused“) 报错如下 解决方法:勾选使用套接字文件

做视频网站需要什么服务器网站建设的编程语言

产品描述 本系列产品,是在该公司研制的专用超大规模集成电路的基础上,研发的点对点多业务光传输设备。此款产品提供4路视频,1-4路电话接口;1-16路开关量接口/1-8路RS232-422-485接口;4路千兆以太网接口(共享…

网站建设管理情况报告seo外链怎么做能看到效果

基于Pix4D使用无人机光学影像制作正射影像(DOM)和数字表面模型(DSM) 操作步骤 0. 前言1.获取无人机光学影像2.DOM和DSM3.操作步骤3.1 初始界面3.2 新建项目3.3查看处理过程报告3.4查看处理进度和成果 4.在ArcMap中打开DSM和DOM 0.…

哪个网站旅游攻略做的最好建设银行广西分行招聘网站

数据库的概念 数据库是按照数据结 构来组织、存储和管理数据的系统,它允许用户高效地存储、检索、更新和管理数据 database:用来组织,存储,管理数据的仓库 数据库的管理系统:DBMS,实现对数据的有效储值&am…

专业电商网站建设多少钱做网站注意事项

💕💕作者:计算机源码社 💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流! 💕&…