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

C++ 使用红黑树的实现及迭代器完成对set和map的封装

一、红黑树的实现以及迭代器

#pragma once
// 要实现完整的迭代器需要对红黑树进行改造,有兴趣可参考侯捷《STL源码剖析》
enum Colour
{
	RED,
	BLACK
};


template<class T>
struct RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;


	T _data;


	Colour _col;


	RBTreeNode(const T& data)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _data(data)
		, _col(RED)
	{}
};


template<class T, class Ref, class Ptr>
struct RBTreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef RBTreeIterator<T, Ref, Ptr> Self;


	Node* _node;


	RBTreeIterator(Node* node)
		:_node(node)
	{}


	// 迭代器的++操作,让迭代器可以移动
	// 左根右,当右没有访问完,就要继续访问
	Self& operator++()
	{
		if (_node->_right)
		{
			// 下一个就是右子树的最左节点
			Node* cur = _node->_right;
			while (cur->_left)
			{
				cur = cur->_left;
			}
			_node = cur;
		}
		else
		{
			// 左子树 根 右子树
			// 右为空,找孩子是父亲左的那个祖先
			Node* cur = _node;
			Node* parent = _node->_parent;
			while (parent && cur == parent->_right)
			{
				cur = parent;
				parent = cur->_parent;
			}
			_node = parent;
		}
		return *this;
	}
    self& operator--()
    {
	    //如果左子树存在
	    if (_node->left)
	    {
		    //找左子树的最右节点
		    Node* right = _node->_left;
		    while (right->_right)
		    {
			    right = right->_right;
		    }
		    _node = rihgt;
	    }
	    //如果左子树不存在
	    else
	    {
		    //找孩子不是父亲左节点的节点
		    Node* parent = _node->parent;
		    Node* cur = _node;
		    while (parent->_left == cur)
		    {
			    cur = cur->_parent;
			    parent = parent->_parent;
			    if (parent == nullptr)
			    {
				    break;
			    }
		    }
		    _node = parent;
	    }
	    return *this;
    }

	// 下面两个操作,让迭代器可以像指针一样操作
	T& operator*()
	{
		return _node->_data;
	}
	T* operator->()
	{
		return &_node->_data;
	}


	// 下面两个操作,让迭代器能够支持比较
	bool operator!=(const Self& s)const
	{
		return _node != s._node;
	}
	bool operator==(const Self& s)const
	{
		return _node == s._node;
	}
};


template<class K, class T, class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef RBTreeIterator<T, T&, T*> Iterator;
	typedef RBTreeIterator<T, const T&, const T*> const_Iterator;
	
	Iterator Begin()
	{
		Node* cur = _root;
		while (cur && cur->_left)
		{
			cur = cur->_left;
		}


		return Iterator(cur);
	}


	Iterator End()
	{
		return Iterator(nullptr);
	}


	const_Iterator Begin() const
	{
		Node* cur = _root;
		while (cur->_left)
			cur = cur->_left;
		return const_Iterator(cur);
	}


	const_Iterator End() const
	{
		return const_Iterator(nullptr);
	}


	~RBTree()
	{
		Destroy(_root);
		_root = nullptr;
	}


	pair<Node*, bool> Insert(const T& data)
	{
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_col = BLACK;
			return make_pair(_root,true);
		}


		KeyOfT kot;
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(cur, false);
			}
		}




		cur = new Node(data);
		Node* newnode = cur;
		// 新增节点。颜色红色给红色
		cur->_col = RED;
		if (kot(parent->_data) < kot(data))
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		cur->_parent = parent;


		while (parent && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			//    g
			//  p   u
			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;
				if (uncle && uncle->_col == RED)
				{
					// u存在且为红 -》变色再继续往上处理
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;




					cur = grandfather;
					parent = cur->_parent;
				}
				else
				{
					// u存在且为黑或不存在 -》旋转+变色
					if (cur == parent->_left)
					{
						//    g
						//  p   u
						//c
						//单旋
						RotateR(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						//    g
						//  p   u
						//    c
						//双旋
						RotateL(parent);
						RotateR(grandfather);




						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break;
				}
			}
			else
			{
				//    g
				//  u   p
				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
					//            c
					if (cur == parent->_right)
					{
						RotateL(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						//		g
						//   u     p
						//      c
						RotateR(parent);
						RotateL(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break;
				}
			}
		}


		_root->_col = BLACK;
		return make_pair(newnode, true);
	}


	bool empty()const
	{
		if (_root == nullptr)
			return true;
		return false;
	}


	Node* Find(const K& key)
	{
		Node* cur = _root;
		while (cur)
		{
			if (cur->_kv.first < key)
			{
				cur = cur->_right;
			}
			else if (cur->_kv.first > key)
			{
				cur = cur->_left;
			}
			else
			{
				return cur;
			}
		}


		return nullptr;
	}


	size_t Size() const
	{
		return _Size(_root);
	}


private:
	size_t _Size(Node* root) const
	{
		if (root == nullptr)
			return 0;


		return _Size(root->_left)
			+ _Size(root->_right) + 1;
	}
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;


		parent->_right = subRL;
		if (subRL)
			subRL->_parent = parent;


		Node* parentParent = parent->_parent;


		subR->_left = parent;
		parent->_parent = subR;




		if (parentParent == nullptr)
		{
			_root = subR;
			subR->_parent = nullptr;
		}
		else
		{
			if (parent == parentParent->_left)
			{
				parentParent->_left = subR;
			}
			else
			{
				parentParent->_right = subR;
			}


			subR->_parent = parentParent;
		}
	}




	void  RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;


		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;


		Node* parentParent = parent->_parent;


		subL->_right = parent;
		parent->_parent = subL;


		if (parentParent == nullptr)
		{
			_root = subL;
			subL->_parent = nullptr;
		}
		else
		{
			if (parent == parentParent->_left)
			{
				parentParent->_left = subL;
			}
			else
			{
				parentParent->_right = subL;
			}
			subL->_parent = parentParent;
		}
	}


	void Destroy(Node* root)
	{
		if (root == nullptr)
			return;


		Destroy(root->_left);
		Destroy(root->_right);
		delete root;
	}


private:
	Node* _root = nullptr;
};

二、set

#pragma once
#include"RBTree_iterator.h"

namespace XY 
{
	template<class K>
	class set
	{
		typedef K ValueType;

		struct KeyOfValue
		{
			const K& operator()(const ValueType& data)
			{
				return data;
			}
		};

	public:
		// 这里加typename的原因是告诉编译器这是模板不是类型
		// 还没实例化
		typedef typename  RBTree<ValueType, ValueType,KeyOfValue>::const_Iterator iterator;
		typedef typename  RBTree<ValueType, ValueType,KeyOfValue>::const_Iterator const_iterator;
		
		iterator begin() const
		{
			return t.Begin();
		}
		iterator end() const
		{
			return t.End();
		}
		
		bool empty()const
		{
			return t.empty();
		}
		size_t size()const
		{
			return t.Size();
		}
		
		pair<iterator, bool> insert(const ValueType& data)
		{
			return t.Insert(data);
		}
		void clear()
		{
			t.Destroy();
		}
		iterator find(const K& key)
		{
			t.Find(key);
		}
	private:
		RBTree<ValueType, ValueType, KeyOfValue> t;
	};
}

三、map

#pragma once

#include"RBTree_iterator.h"

namespace XY   
{
	template<class K, class V>
	class map
	{
		typedef pair<K, V> ValueType;
		struct KeyOfValue
		{
			const K& operator()(const ValueType& data)
			{
				return data.first;
			}
		};

	public:
		// 这里加typename的原因是告诉编译器这是模板不是类型
		// 还没实例化
		typedef typename RBTree<ValueType, pair<const K, V>, KeyOfValue>::Iterator iterator;
		typedef typename RBTree<ValueType, pair<const K, V>, KeyOfValue>::const_Iterator const_iterator;

		iterator begin()
		{
			return t.Begin();
		}
		iterator end()
		{
			return t.End();
		}
		const_iterator cbegin() const
		{
			return t.Begin();
		}
		const_iterator cend() const
		{
			return t.End();
		}

		bool empty()const
		{
			return t.empty();
		}
		size_t size()const
		{
			return t.Size();
		}
		
		V& operator[](const K& key)
		{
			pair<iterator, bool> ret = insert(make_pair(key, V()));
			return ret.first->second;
		}

		pair<iterator, bool> insert(const ValueType& data)
		{
			return t.Insert(data);
		}
		void clear()
		{
			t.Destroy();
		}
		iterator find(const K& key)
		{
			t.Find(key);
		}

	private:
		RBTree<ValueType, pair<const K, V>, KeyOfValue> t;
	};
}

相关文章:

  • 2025年Draw.io最新版本下载安装教程,附详细图文
  • asm磁盘组扩容加错磁盘
  • 脑电波控制设备:基于典型相关分析(CCA)的脑机接口频率精准解码方法
  • Tomcat下载安装及日志乱码问题解决
  • DeepSeek-专家并行(二)
  • Spring Boot+RabbitMQ+Canal 解决数据一致性
  • 【算法学习计划】动态规划 -- 路径问题
  • 1433抓鸡工具_1433抓鸡工具在软件安全测试中的重要性及应用
  • Mysql主从复制和Mysql高可用以及负载均衡配置
  • 项目管理起源是什么
  • EDIFACT端口配置指南:交换头、测试标识符与ACK
  • 如何去除文章的 AI 痕迹
  • 设计模式文章汇总-Golang语言实现
  • 第六次CCF-CSP认证(含C++源码)
  • 2025人工智能AI新突破:PINN内嵌物理神经网络火了
  • Linux第六讲:进程控制
  • 晋升系列4:学习方法
  • [内网渗透] 红日靶场1
  • DMA直接存储器存取
  • 初次体验Tauri和Sycamore(3)通道实现
  • 言短意长|党政主官如何塑造流量城市?
  • 五一小长假上海“人从众”,全要素旅游交易总额超200亿元
  • 竞彩湃|新科冠军利物浦留力?纽卡斯尔全力冲击欧冠
  • 消息人士称以色列政府初步同意扩大对加沙军事行动
  • 上海环球马术冠军赛开赛,一场体育与假日消费联动的狂欢
  • 奥斯卡新规:评委必须看完影片再投票;网友:以前不是啊?