C++ 泛型编程 实现红黑树RBTree

代码如下:

#include <iostream>
#include <ctime>
using namespace std;enum COLOR
{BLACK,RED
};template<typename T>
struct RBTreeNode
{RBTreeNode<T> * _parent;RBTreeNode<T> * _left;RBTreeNode<T> * _right;T _val;COLOR _color;RBTreeNode(const T & val = T()):_parent(nullptr),_left(nullptr),_right(nullptr),_val(val),_color(RED){}};template<typename T>
class RBTree
{
public:typedef RBTreeNode<T> Node;RBTree():_root(nullptr){}bool insert(const T & val){if (_root == nullptr) {_root = new Node(val);_root->_color = BLACK;return true;}Node *cur = _root;Node *parent = nullptr;//1.寻找要插入的结点的位置while (cur){parent = cur;if (cur->_val == val) return false;else if (cur->_val > val) cur = cur->_left;else cur = cur->_right;}//2.创建结点cur = new Node(val);if (parent->_val > cur->_val) parent->_left = cur;else parent->_right = cur;cur->_parent = parent;//3.颜色的修改或者结构的调整while (cur != _root && cur->_parent->_color == RED)//不为根且存在连续红色,则需要调整{parent = cur->_parent;Node *gfather = parent->_parent;if (gfather->_left == parent){Node *uncle = gfather->_right;//情况1.uncle存在且为红if (uncle && uncle->_color == RED){parent->_color = uncle->_color = BLACK;gfather->_color = RED;//向上追溯cur = gfather;}else{if (parent->_right == cur){RotateL(parent);swap(cur, parent);}//情况2.uncle不存在或者uncle为黑RotateR(gfather);parent->_color = BLACK;gfather->_color = RED;break;}}else{Node *uncle = gfather->_left;if (uncle && uncle->_color == RED){parent->_color = uncle->_color = BLACK;gfather->_color = RED;//向上追溯cur = gfather;}else{if (parent->_left == cur){RotateR(parent);swap(cur, parent);}RotateL(gfather);parent->_color = BLACK;gfather->_color = RED;break;}}}//根结点都为黑色_root->_color = BLACK;return true;}void RotateL(Node *parent){Node *subR = parent->_right;Node *subRL = subR->_left;parent->_right = subRL;if (subRL) subRL->_parent = parent;if (parent == _root){_root = subR;subR->_parent = nullptr;}else{Node *gfather = parent->_parent;if (gfather->_left == parent) gfather->_left = subR;else gfather->_right = subR;subR->_parent = gfather;}subR->_left = parent;parent->_parent = subR;}void RotateR(Node * parent){Node *subL = parent->_left;Node *subLR = subL->_right;parent->_left = subLR;if (subLR) subLR->_parent = parent;if (parent == _root){_root = subL;subL->_parent = nullptr;}else{Node *gfather = parent->_parent;if (gfather->_left == parent) gfather->_left = subL;else gfather->_right = subL;subL->_parent = gfather;}subL->_right = parent;parent->_parent = subL;}void inorder(){_inorder(_root);cout << endl;}
//红黑树的性质:
//	1.每个结点的颜色只有红色和黑色,且根结点必须为黑色
//	2.不能存在连续的红色结点
//	3.对于每个结点来说,从该结点到其所有后代结点的简单路径上,经过的黑色结点的数目应该是相同的bool isRBTree(){if (_root == nullptr) return true;//空树也属于红黑树if (_root->_color == RED) return false;//不满足性质2:根结点必须为黑色int bCount = 0;//从某条路径上的黑色结点数Node *cur = _root;while (cur){if (cur->_color == BLACK) ++bCount;cur = cur->_left;}int pathCount = 0;return _isRBTree(_root, bCount, pathCount);}bool _isRBTree(Node *root, const int bCount, int pathCount){if (root == nullptr)//路径走完,判断黑色结点个数{if (pathCount == bCount) return true;else return false;//不满足性质3:每一条路径上的黑色结点个数相同}if (root->_color == BLACK) ++pathCount;Node *parent = root->_parent;if (parent && parent->_color == RED && root->_color == RED) return false;//不满足性质2:不能存在连续的红色结点return _isRBTree(root->_left, bCount, pathCount) && _isRBTree(root->_right, bCount, pathCount);}private:Node *_root;void _inorder(Node *root){if (root){_inorder(root->_left);cout << root->_val << " ";_inorder(root->_right);}}
};int main()
{RBTree<int> rbt;srand(time(nullptr));int n;cout << "num = " << endl;cin >> n;for (int i = 0; i < n; i++){rbt.insert(rand());}rbt.inorder();if (rbt.isRBTree()) cout << "yes" << endl;else cout << "no" << endl;return 0;
}

测试结果:

在这里插入图片描述

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

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

相关文章

数据结构与算法--图论-深度优先搜索及其应用

深度优先搜索 深度优先搜索&#xff08;depth-first search&#xff09; 是对先序遍历&#xff08;preorder traversal&#xff09;的推广&#xff0c;我们从某个顶点v开始处理v&#xff0c;然后递归的遍历所有与v邻接顶点。如果这个过程是对一棵树进行&#xff0c;那么&#…

.NET Core技术研究-主机

前一段时间&#xff0c;和大家分享了 ASP.NET Core技术研究-探秘Host主机启动过程但是没有深入说明主机的设计。今天整理了一下主机的一些知识&#xff0c;结合先前的博文&#xff0c;完整地介绍一下.NET Core的主机的设计和构建启动过程。一、什么是主机主机是一个封装了应用资…

数据结构与算法--贪婪算法

贪婪算法 贪婪算法分阶段地工作。在每个阶段&#xff0c;可以认为所做决定是最好的&#xff0c;而不考虑将来的后果。通常这意味着选择的是某个局部最优。这种“当前能获得的最优就拿”的策略是这类算法的名字来源。当算法终止时候&#xff0c;我们希望的到累积的局部最优解就…

[C++STL]C++ 实现map容器和set容器

代码如下: #pragma once #include <iostream> using namespace std;enum COLOR {BLACK, RED };template<class V>//迭代器声明&#xff0c;定义在后面 struct RBTreeIterator;template<typename V> struct RBTreeNode {RBTreeNode<V> * _parent;RBTre…

多角度让你彻底明白yield语法糖的用法和原理及在C#函数式编程中的作用

如果大家读过dapper源码&#xff0c;你会发现这内部有很多方法都用到了yield关键词&#xff0c;那yield到底是用来干嘛的&#xff0c;能不能拿掉&#xff0c;拿掉与不拿掉有多大的差别&#xff0c;首先上一段dapper中精简后的Query方法&#xff0c;先让大家眼见为实。private s…

C++泛型编程实现哈希表(闭散列---线性探测)

代码如下: #include <iostream> #include <vector> using namespace std;enum STATE {EXIST,DELETE,EMPTY };template<typename K,typename V> struct HashNode {pair<K, V> _kv;STATE _state EMPTY; };template<typename K,typename V> class…

哪种开源许可证最适合商业化?

选择最佳开源许可证是为新项目所做的最重要的决定之一。大多数开发者会选用 MIT、BSD 或 Apache 等流行的宽松许可证&#xff08;permissive license&#xff09;。对于商业项目而言&#xff0c;这种选择不错&#xff0c;因为这能减少用户对项目的抵触情绪。当应用于开源项目时…

C++泛型编程实现哈希表(开散列法)

代码如下: #include <iostream> #include <vector> using namespace std;template<typename K> struct HashNode {typedef HashNode<K> Node;K _val;Node * _next;HashNode(const K & val):_val(val),_next(nullptr){} };template<typename K&…

数据结构与算法--分治算法-最大子序列和问题

分治算法 用于设计算法的一种常用技巧–分治算法&#xff08;divide and conquer&#xff09;。分治算法由两部分组成&#xff1a; 分(divide)&#xff1a;递归然后借机较小的问题&#xff08;基础情况除外&#xff09;治(conquer)&#xff1a;然后从子问题的解构建原问题的解…

请把我不会,换成我可以学

点击蓝字关注&#xff0c;回复“职场进阶”获取职场进阶精品资料一份有位读者跟我说起自己的烦恼&#xff1a;“我到公司已经接近四年了&#xff0c;领导经常让我做一些岗位职责以外的事情。这些东西我都不会&#xff0c;还非让我做。并且一直没有职位上的改变&#xff0c;我怎…

[C++STL]C++实现unordermap容器和unorderset容器

代码如下: #include <iostream> #include <vector> using namespace std;template<typename K,typename V,typename KeyOfValue> class HashTable;//声明template<typename V> struct HashNode {typedef HashNode<V> Node;V _val;Node * _next;…

还不会docker+k8s?2020年,就要面对现实了...

docker的前世今生2010年&#xff0c;几个年轻人&#xff0c;在美国旧金山成立了一家名叫“dotCloud”的公司。这家公司主要提供基于PaaS的云计算技术服务。具体来说&#xff0c;是和LXC有关的容器技术。后来&#xff0c;dotCloud公司将自己的容器技术进行了简化和标准化&#x…

数据结构与算法--重建二叉树

二叉树 树在实际编程中经常遇到地一种数据结构。上一篇中我们解释了二叉树及其原理&#xff0c;从中可以知道&#xff0c;树地操作会涉及到很多指针地操作&#xff0c;我们一般遇到地树相关地问题差不多都是二叉树。二叉树最重要地莫过于遍历&#xff0c;即按照某一顺序访问树…

3分钟掌握Quartz.net分布式定时任务的姿势

长话短说&#xff0c;今天聊一聊分布式定时任务&#xff0c;我的流水账笔记&#xff1a;ASP.NET CoreQuartz.Net实现web定时任务AspNetCore结合Redis实践消息队列细心朋友稍一分析&#xff0c;就知道还有问题&#xff1a;水平扩展后的WebApp的Quartz.net定时任务会多次触发&…

数据结构与算法--利用栈实现队列

利用栈实现队列 上一节中说明了栈的特点 后进先出&#xff0c;我们用数组的方式实现了栈的基本操作api&#xff0c;因此我们对栈的操作是不考虑排序的&#xff0c;每个api的操作基本都是O(1)的世界&#xff0c;因为不考虑顺序&#xff0c;所以找最大&#xff0c;最小值&#x…

ASP.NET Core 配置源:实时生效

在之前的文章 ASP.NET Core 自定义配置源 和 ASP.NET Core etcd 配置源 中主要是介绍如何实现自定义的配置源&#xff0c;但不论内置的和自定义的配置源&#xff0c;都会面临如何使配置修改后实时生效的问题&#xff08;修改配置后在不重启服务的情况下能马上生效&#xff09;。…

分布式事务理论模型

分布式事务 事务的概念&#xff0c;我们第一想到的应该是数据库的事务。所谓数据库事务就是只作为单个逻辑工作单元执行多个数据库操作的时候&#xff0c;数据库需要保证要么都成功&#xff0c;要么都失败&#xff0c;它必须满足ACID特性&#xff0c;即&#xff1a; 原子性&…

[MySQL基础]数据库的相关概念

DB: 数据库(database):存储数据的“仓库”&#xff0c;它保存了一系列有组织的数据。 DBMS: 数据库管理系统(Database Management System):数据库是通过DBMS创建和操作的容器。 SQL: 结构化查询语言(Structure Query Language):专门用来与数据库通信的语言。 SQL的优点: 1.几…

Linq下有一个非常实用的SelectMany方法,很多人却不会用

在平时开发中经常会看到有些朋友或者同事在写代码时会充斥着各种for&#xff0c;foreach&#xff0c;这种程式代码太多的话阅读性特别差&#xff0c;而且还显得特别累赘&#xff0c;其实在FCL中有很多帮助我们提高阅读感的方法&#xff0c;而现实中很多人不会用或者说不知道&am…