一、map和set的实现

实现STL中的map与set底层使用的是map和set

1.1底层红黑树的实现(RBTree.h):

#pragma once
#include<iostream>
#include<set>
#include<assert.h>
#include<stdbool.h>
#include<time.h>
#include<vector>
#include<string>
using namespace std;
enum color
{
	RED,
	BLACK
};
template<typename T>
class RBTreeNode
{
public:
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	T _data;
	color _color;
	RBTreeNode(const T& data)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _data(data)
		, _color(RED)
	{
	}
};
template<class T, class Ptr, class Ref>
struct __TreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef __TreeIterator<T, Ptr, Ref> self;
	typedef __TreeIterator<T, T*, T&> iterator;

	Node* _node;
	__TreeIterator(Node* node)
		:_node(node)
	{
	}

	__TreeIterator(const iterator& it)
		:_node(it._node)
	{

	}
	Ref operator*()
	{
		return _node->_data;
	}
	Ptr operator->()
	{
		return &_node->_data;
	}
	bool operator!=(const self& s) const
	{
		return _node != s._node;
	}
	bool operator==(const self& s) const
	{
		return _node == s._node;
	}
	self& operator--()
	{
		//左子树存在
		if (_node->_left)
		{
			//找左子树的最右侧结点
			Node* rightmost = _node->_left;
			while (_node->_right)
			{
				rightmost = rightmost->_right;
			}
			_node = rightmost;
		}
		else//左子树不存在
		{
			Node* cur = _node;
			Node* parent = _node->_parent;
			//要找到孩子是父亲右的那个结点
			while (parent && cur == parent->_left)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}
	self& operator++()//两种情况:1、右节点存在 2、右节点不存在
	{
		if (_node->_right)//右节点存在
		{
			//此时要访问右树的最左边结点
			Node* leftmost = _node;
			while (leftmost->_left)
			{
				leftmost = leftmost->_left;
			}
			_node = leftmost;
		}
		else//右节点不存在
		{
			//此时要访问这个结点的父亲结点
			Node* cur = _node;
			Node* parent = cur->_parent;
		
			while (parent && cur = parent->_right)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}
};
template<typename K, typename T, class KeyOfT>
class RBTree
{
public:
	typedef RBTreeNode<T> Node;

	//这里的iterator和const_iterator是同一个类模板,传的不同的参数实例化出的不同类型
	typedef __TreeIterator<T, T*, T&> iterator;
	typedef __TreeIterator<T, const T*, const T&> const_iterator;

	//迭代器  
	iterator begin()
	{
		Node* leftmost = _root;
		while (leftmost && leftmost->_left)
		{
			leftmost = leftmost->_left;
		}
		return iterator(leftmost);
	}

	iterator end()
	{
		return iterator(nullptr);
	}
	
	const_iterator begin() const
	{
		Node* leftmost = _root;
		while (leftmost && leftmost->_left)
		{
			leftmost = leftmost->_left;
		}
		return const_iterator(leftmost);
	}
	const_iterator end() const
	{
		return const_iterator(nullptr);
	}

	
	//查找
	Node* Find(const K& key)
	{
		Node* cur = _root;
		KeyOfT kt;
		while (cur)
		{
			if (kt(cur->_data) < key)
			{
				cur = cur->_right;
			}
			else if (kt(cur->_data) > key)
			{
				cur = cur->_left;
			}
			else
			{
				return cur;
			}
		}
		return nullptr;
	}

	//插入
	pair<iterator,bool> Insert(const T& data )//这里的T是key就是set,key是pair就是map
	{
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_color = BLACK;//根节点设置成黑色
			return make_pair(iterator(_root), true);
		}

		Node* cur = _root;
		Node* parent = nullptr;

		//把key取出来
		KeyOfT kt;
		while (cur)
		{
			if (kt(cur- >_data) < kt(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kt(cur->_data) > kt(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				//返回已经有的这个结点的迭代器
				return make_pair(iterator(cur), false);
			}
		}
		cur = new Node(data);
		Node* newnode = cur;
		cur->_color = RED;//把除根节点以外的节点首次设置成红色
		//把新结点链接到上一个结点的后面
		if (kt(parent->_data) < kt(data))
		{
			parent->_right = cur;
		}
		else if (kt(parent->_data) > kt(data))
		{
			parent->_left = cur;
		}
		else
		{
			assert(false);
		}
		cur->_parent = parent;

		//对颜色进行调节
		while (parent && parent->_color == RED)
		{
			Node* grandfather = parent->_parent;
			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;

				if (uncle && uncle->_color == RED)//uncle存在且为红色
				{
					//变色处理
					uncle->_color = BLACK;
					parent->_color = BLACK;
					grandfather->_color = RED;
					//继续向上处理
					cur = grandfather;
					parent = cur->_parent;
				}
				else//uncle不存在或者uncle为黑色
				{
					if (cur == parent->_left)//cur在parent左边,进行单旋
					{
						//对grandfather进行右旋
						RotateR(grandfather);
						//对parent和grandfather进行颜色的更改
						parent->_color = BLACK;
						grandfather->_color = RED;
					}
					else//cur在parent的右边,进行双旋
					{
						//先对parent进行左旋
						RotateL(parent);
						//在对grandfather进行右旋
						RotateR(grandfather);
						grandfather->_color = RED;
						cur->_color = BLACK;
					}
					break;
				}
			}
			else//parent在grandfather的右边
			{
				Node* uncle = grandfather->_left;

				if (uncle && uncle->_color == RED)//uncle存在且uncle为红色
				{
					//变色处理
					parent->_color = BLACK;
					grandfather->_color = RED;
					uncle->_color = BLACK;
					//继续向上处理
					cur = grandfather;
					parent = cur->_parent;
				}
				else//uncle不存在或者uncle为黑色
				{
					if (cur == parent->_right)//cur在parent的右边(cur和pg在一条直线上)
					{
						//向左进行旋
						RotateL(grandfather);
						//颜色处理
						parent->_color = BLACK;
						grandfather->_color = RED;
					}
					else//cur在parent的左边
					{
						//先进行右旋
						RotateR(parent);
						//在进行左旋
						RotateL(grandfather);
						cur->_color = BLACK;
						grandfather->_color = RED;
					}
					break;
				}
			}
		}
		_root->_color = BLACK;
		return make_pair(iterator(newnode), true);
	}
	//左单旋
	void RotateL(Node* parent)
	{

		Node* cur = parent->_right;
		Node* curleft = cur->_left;

		parent->_right = curleft;
		if (curleft)
		{
			curleft->_parent = parent;
		}

		cur->_left = parent;

		Node* ppnode = parent->_parent;

		parent->_parent = cur;


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

			}

			cur->_parent = ppnode;
		}
	}
	//右单旋
	void RotateR(Node* parent)
	{

		Node* cur = parent->_left;
		Node* curright = cur->_right;

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

		Node* ppnode = parent->_parent;
		cur->_right = parent;
		parent->_parent = cur;

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

			cur->_parent = ppnode;
		}
	}
	//红黑树判断是否平衡
	bool CheckColor(Node* root, int blacknum, int benchmark)//此处不加引用算的是每条路径上的节点数量
	{
		if (root == nullptr)
		{
			if (blacknum != benchmark)
			{
				return false;
			}
			return true;
		}

		if (root->_color == BLACK)
		{
			++blacknum;
		}

		if (root->_color == RED && root->_parent && root->_parent->_color == RED)
		{
			cout << "root->_kv.first" << "出现连续的红色结点" << endl;
			return false;
		}

		return CheckColor(root->_left, blacknum, benchmark) && CheckColor(root->_right, blacknum, benchmark);
	}
	bool _IsBalance()
	{
		return IsBalance(_root);
	}
	bool IsBalance(Node* root)
	{
		if (root == nullptr)
		{
			return true;
		}
		//检查根节点是否为黑色
		if (root->_color != BLACK)
		{
			return false;
		}

		//求出最左路径作为基准值
		int benchmark = 0;
		Node* cur = root;
		while (cur)
		{
			if (cur->_color == BLACK)
			{
				++benchmark;
			}
			cur = cur->_left;
		}
		//检查是否右连续的红色结点
		return CheckColor(root, 0, benchmark);
	}
	//求高度
	int Height()
	{
		return Height(_root);
	}

	int Height(Node* root)
	{
		if (root == nullptr)
			return 0;

		int leftHeight = Height(root->_left);
		int rightHeight = Height(root->_right);

		return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
	}
protected:
	Node* _root = nullptr;
};

1.2map和set的实现:

1.2.1map的实现(My_Map.h):

#pragma once
#include"RBTree.h"

namespace my_map
{
	template<typename K, class V>
	class map
	{
	public:
		struct MapKeyOfT
		{
			const K& operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
		typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::iterator iterator;
		typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::const_iterator const_iterator;

		iterator begin()
		{
			return _t.begin();
		}
		iterator end()
		{
			return _t.end();
		}

		const_iterator begin() const
		{
			return _t.begin();
		}
		const_iterator end() const 
		{
			return _t.end();
		}
		//插入
		pair<iterator,bool> insert(const pair<K, V>& kv)
		{
			return _t.Insert(kv);
		}
		V& operator[](const K& key)
		{
			pair<iterator, bool> ret = insert(make_pair(key), V());
			return ret.first->second;
		}
	protected:
		RBTree<K, pair<const K, V>, MapKeyOfT> _t;
	};
}

1.2.2set的实现(My_Set.h):

#pragma once
#include "RBTree.h"

namespace my_set
{
	template<typename K>
	class set
	{
		struct SetKeyOfT
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	public:
		//类模板里取内嵌类型加typename
		typedef typename RBTree<K, K, SetKeyOfT>::const_iterator iterator;
		typedef typename RBTree<K, K, SetKeyOfT>::const_iterator const_iterator;

		iterator begin()
		{
			return _t.begin();
		}
		iterator end()
		{
			return _t.end();
		}
		const_iterator begin() const
		{
			return _t.begin();
		}
		const_iterator end() const
		{
			return _t.end();
		}
		
		//插入
		pair<iterator,bool> insert(const K& key)
		{
			pair< typename RBTree<K, K, SetKeyOfT>::iterator, bool> ret = _t.Insert(key);
			return pair<iterator, bool>(ret.first, ret.second);
			//return中pair里面的iterator是const_iterator
		}
	protected:
		RBTree<K, K, SetKeyOfT> _t;
	};
}

二、模拟实现的map和set进行测试

#include "My_Map.h"
#include "My_Set.h"
int main()
{
	//set测试
	my_set::set<int> s1;
	s1.insert(2);
	s1.insert(5);
	s1.insert(8);

	my_set::set<int>::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	//范围for
	for (const auto& element : s1)
	{
		cout << element;
	}
	cout << endl;


	//map测试
	my_map::map<string, string> dict;
	dict.insert(make_pair("love", "爱"));
	dict.insert(make_pair("insert", "插入"));
	dict.insert(make_pair("miss", "错过、想念"));

	my_map::map<string, string>::iterator it2 = dict.begin();
	while (it2 != dict.end())
	{
		cout << it2->first << ":" << it2->second;
		++it2;
	}
	cout << endl;

	//范围for
	for (const auto& element : dict)
	{
		cout << element.first << ":" << element.second;
	}
	cout << endl;

	my_map::map<string, int> countmap;
	countmap["西瓜"];//插入
	countmap["冬瓜"] = 1;//插入+修改
	countmap["西瓜"] = 2;//修改

	return 0;
 }

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐