map和set的简易封装(纯代码)

RBTree.h

#pragma once

#include<iostream>
#include<vector>
using namespace std;

enum colar
{   
	red,
	black
};

template<class T>//有效参数就一个 
struct RBTreeNode
{
	RBTreeNode(const T& data)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _data(data)
		, _co(red)
	{}

	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;

	T _data;
	colar _co;

};

template<class T,class ref,class ptr>
struct _Tree_iterator
{
	typedef RBTreeNode<T> Node;
	typedef _Tree_iterator<T,ref,ptr> self;
	Node* _cur;

	_Tree_iterator(Node* tmp)
		:_cur(tmp)
	{}

	self& operator++()
	{
		//将当前节点看作父节点再分析
		if (_cur->_right == nullptr)//向上返回(前提是父的左孩子)如果是右孩子则表明父亲已经遍历过了
		{
			Node* parent = _cur->_parent;
			while (parent && parent->_right == _cur)//parent可能为空
			{
				_cur = parent;
				parent = _cur->_parent;
			}
			//指向parent指向的left等于_cur 或者parent为空(遍历结束)
			_cur = parent;

		}
		else//自己就属于父节点,找右子树的最左节点
		{
			Node* tmp = _cur->_right;
			while (tmp->_left)//tmp不可能为空
			{
				tmp = tmp->_left;
			}
			_cur = tmp;
		}
		return *this;
	}
	self& operator--()//相较于operator++而言就是 右子树 根 左子树 的遍历方式
	{
		if (_cur->_left == nullptr)//表明当前节点遍历完成,向上返回……
		{
			Node* parent = _cur->_parent;
			while (parent&&parent->_left == _cur)
			{
				_cur = parent;
				parent = parent->_parent;
			}
			_cur = parent;
		}
		else
		{
			//找左子树的最右节点
			_cur = _cur->_left;
			while (_cur->_right)
			{
				_cur = _cur->_right;
			}
		}
		return *this;
	}

	ref operator*()
	{
		return _cur->_data;
	}

	ptr operator->()
	{
		return &_cur->_data;
	}

	bool operator!=(const self& tmp)
	{
		return _cur != tmp._cur;
	}
};

template<class K, class T,class Com_T>
class RBTree
{
	typedef RBTreeNode<T> Node;
	
public:
	typedef _Tree_iterator<T,T&,T*> iterator;
	typedef _Tree_iterator<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 cbegin()const
	{
		Node* cur = _root;
		while (cur && cur->_left)
		{
			cur = cur->_left;
		}
		return const_iterator(cur);
	}
	const_iterator cend()const 
	{
		return const_iterator(nullptr);
	}

	//pair <iterator, bool> insert(const T& data)//data类型取决于T,而T又取决于map和set
	pair <Node*, bool> insert(const T& data)//data类型取决于T,而T又取决于map和set
	{
		Node* newroot = new Node(data);//默认为红
		if (_root == nullptr)
		{
			_root = newroot;
			_root->_co = black;//设为黑
			return make_pair(newroot,true);
		}
		Node* parent = _root, * cur = _root;
		//插入数据
		Com_T com;
		while (1)
		{
			parent = cur;
			if (com(cur->_data) > com(data))//这里data的类型可能是pair(不确定)
			{
				cur = cur->_left;
				if (cur == nullptr)
				{
					parent->_left = newroot;
					newroot->_parent = parent;
					break;
				}
			}
			else if (com(cur->_data) < com(data))
			{
				cur = cur->_right;
				if (cur == nullptr)
				{
					parent->_right = newroot;
					newroot->_parent = parent;
					break;
				}
			}
			else
			{
				return make_pair(cur, false);//数据相同返回相同数据的迭代器(类似是查找数据)
			}

		}

		//父节点的判断
		cur = newroot;//当前节点就是新插入的节点

		while (parent && parent->_co == red)//父亲节点可能不存在
		{
			Node* pparent = parent->_parent;//parent为红,不可能是根,一定存在pparent
			Node* uncle = nullptr;
			//找叔叔节点
			if (pparent->_right == parent)
				uncle = parent->_parent->_left;
			else
				uncle = parent->_parent->_right;

			if (uncle && uncle->_co == red)//叔叔存在且为红
			{
				//变色
				parent->_co = uncle->_co = black;
				pparent->_co = red;//祖父节点有可能是根节点
				//继续向上更新处理
				cur = pparent;
				parent = cur->_parent;
			}
			else//叔叔节点为空或为黑
			{
				//旋转
				if (pparent->_left == parent && parent->_left == cur)
				{
					//右单旋
					RotateR(pparent);
					parent->_co = black;
					pparent->_co = red;
				}
				else if (pparent->_right == parent && parent->_right == cur)
				{
					//左单旋
					RotateL(pparent);
					parent->_co = black;
					pparent->_co = red;
				}
				else if (pparent->_right == parent && parent->_left == cur)
				{
					//右左双旋
					RotateR(parent);
					RotateL(pparent);
					cur->_co = black;
					pparent->_co = red;
				}
				else if (pparent->_left == parent && parent->_right == cur)
				{
					//左右双旋
					RotateL(parent);
					RotateR(pparent);
					cur->_co = black;
					pparent->_co = red;
				}
				break;//旋转之后新的根节点都是黑色
			}

		}

		_root->_co = black;//循环体内很有可能将根节点改为红
		return make_pair(newroot, true);

	}


	void RotateL(Node* parent)//左单旋
	{
		Node* cur = parent->_right;
		Node* curl = cur->_left;
		Node* pparent = parent->_parent;//提前记录

		parent->_right = curl;
		if (curl)
		{
			curl->_parent = parent;
		}
		cur->_left = parent;
		parent->_parent = cur;

		//处理pparent与parent的连接
		if (_root == parent)
		{
			_root = cur;
			cur->_parent = nullptr;
		}
		else
		{
			if (pparent->_left == parent)
				pparent->_left = cur;
			else
				pparent->_right = cur;
			cur->_parent = pparent;
		}

	}
	void RotateR(Node* parent)//右单旋
	{
		{
			Node* cur = parent->_left;
			Node* curr = cur->_right;
			Node* pparent = parent->_parent;//提前记录

			parent->_left = curr;
			if (curr)
			{
				curr->_parent = parent;
			}
			cur->_right = parent;
			parent->_parent = cur;

			//处理pparent与parent的连接
			if (_root == parent)
			{
				_root = cur;
				cur->_parent = nullptr;
			}
			else
			{
				if (pparent->_left == parent)
					pparent->_left = cur;
				else
					pparent->_right = cur;
				cur->_parent = pparent;
			}

		}
	}

	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
	void _InOrder(Node* root)
	{
		if (root == nullptr)
			return;

		_InOrder(root->_left);
		cout << root->_kv.first << " ";
		_InOrder(root->_right);
	}

	// 根节点->当前节点这条路径的黑色节点的数量
	bool Check(Node* cur, int blacknum, int ref_val)
	{
		if (cur == nullptr)
		{
			if (blacknum == ref_val)
				return true;
			cout << "每条路径的黑色节点个数不同" << endl;
			return false;
		}
		Node* parent = cur->_parent;
		if (cur->_co == red && parent->_co == red)//向上判断,向下判断的节点可能为空或其它的。
			return false;
		if (cur->_co == black)
			blacknum++;

		return Check(cur->_left, blacknum, ref_val) && Check(cur->_right, blacknum, ref_val);
	}
	bool Is_balance()
	{
		if (_root->_co == red)
			return false;
		if (_root == nullptr)
			return true;

		//不能出现连续红节点
		//每条路径黑色节点要保证相同
		int blacknum = 0;//必须传值,相当于是每个节点都有一个变量表示从根到当前的黑节点个数
		int ref_val = 0;//参考值,求出任意一条路径中黑色节点数目
		Node* cur = _root;
		while (cur)
		{
			if (cur->_co == black)
				ref_val++;
			cur = cur->_left;
		}
		return Check(_root, blacknum, ref_val);
	}

private:
	Node* _root=nullptr;
};

Set.h

#include"RBTree.h"

template<class  key>
class set
{
public:
	struct setCom//仿函数
	{
		const key& operator()(const key& k)
		{
			return k;
		}
	};

	//typedef _Tree_iterator<key> iterator;
	typedef typename RBTree<key, key, setCom>::const_iterator iterator;
	typedef typename RBTree<key, key, setCom>::const_iterator const_iterator;
	//对类模版取内嵌类型,加typename是为了告诉编译器这里是类型

	pair<iterator,bool> insert(const key& k)//此时pair的第一个参数类型是const_iterator
	{
		return _s.insert(k);//insert返回pair<Node*,bool>会构造出pair<iterator,bool>
	}

	iterator begin()const
	{
		return _s.cbegin();
	}
	iterator end()const
	{
		return _s.cend();
	}
	

private:
	RBTree<key, key, setCom> _s;//封装红黑树
};

Map.h

#include"RBTree.h"

template<class  key,class val>
class map
{
public:

	struct mapCom//仿函数
	{
		const key& operator()(const pair<key,val>& p)
		{
			return p.first;
		}
	}; 

	//typedef _Tree_iterator<pair<key,val>> iterator;
	typedef typename RBTree<key, pair<const key, val>, mapCom>::iterator iterator;
	typedef typename RBTree<key, pair<const key, val>, mapCom>::const_iterator const_iterator;
	//对类模版取内嵌类型,加typename是为了告诉编译器这里是类型

	pair<iterator, bool> insert(const pair<key, val>& kv)
	{
		return _m.insert(kv);
	}
	
	iterator begin()
	{
		return _m.begin();
	}
	iterator end()
	{
		return _m.end();
	}
	const_iterator cbegin()const
	{
		return _m.cbegin();
	}
	const_iterator cend()const
	{
		return _m.cend();
	}

	val& operator[](const key& k)
	{
		pair<key, val> tmp(k, val());//val给缺省值,tmp是创建变量
		pair<iterator,bool> ret = insert(tmp);//返回插入的节点的pair

		return (ret.first)->second;
	}

private: 
	RBTree<key, pair<const key, val>,mapCom> _m;//封装红黑树(参数类型决定着红黑树的数据类型)
};  

test.cpp(测试)

#include"Map.h"
#include"Set.h"
#include<string>

void test_set()
{
	set<int> s;
	s.insert(4);
	s.insert(1);
	s.insert(2);
	s.insert(3);
	s.insert(2);
	s.insert(0);
	s.insert(10);
	s.insert(5);

	set<int>::iterator it = s.begin();//浅拷贝
	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;
}

void test_map()
{
	map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("sort", "xx"));
	dict.insert(make_pair("left", "左边"));
	dict.insert(make_pair("right", "右边"));

	map<string, string>::const_iterator it = dict.cbegin();
	while (it != dict.cend())
	{
		cout << it->first << ":" << it->second << endl;
		++it;
	}
	cout << endl;

	string arr[] = { "㽶", "香蕉","ƻ", "香蕉", "ƻ", "香蕉", "ƻ", "ƻ", "香蕉", "ƻ", "㽶", "ƻ", "㽶" };
	map<string, int> countMap;
	for (auto& e : arr)
	{
		countMap[e]++;
	}

	for (auto kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;
}

int main()
{
	//test_set();
	test_map();

	return 0;
}

如有问题欢迎留言!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CR0712

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值