cpp笔记map和set

map和set的实现难点在于,他们都是使用红黑树为载体,实现map和set两并不相同的数据结构。

map存在着​pair<const key_type,mapped_type> ,而set存着key,但是他们用着同一颗红黑树,用的就是模板的魅力.

话不多说先看代码:Mymap

namespace xiaobo
{
	template<class K,class V>
	class map
	{
		struct MapKeyOfT//解决一颗树,适用两个数据结构
		{
			K& operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
		typedef typename RBTree<K, V, MapKeyOfT>::iterator iterator;

		iterator begin()
		{
			return _t.begin();
		}
		iterator end()
		{
			return _t.end();
		}
		bool Insert(const K& k)
		{
			return _t.Insert(k);
		}
		bool Insert(const pair<K, V>& kv)
		{
			return _t.Insert(kv);
		}
	private:
		RBTree<K, pair<K, V>,MapKeyOfT> _t;//用两个不同的类,来确定是key还是​pair<const key_type,mapped_type>
	};
}

Myset

namespace xiaobo
{
	template<class K>
	class set
	{
		struct SetKeyOfT//用两个不同的类,来确定是key还是​pair<const key_type,mapped_type>
		{
			K& operator()(const K& k)
			{
				return k;
			}
		};
	public:
		typedef typename RBTree<K, K, SetKeyOfT>::iterator iterator;//迭代器

		iterator begin()//开始
		{
			return _t.begin();
		}
		iterator end()//结束
		{
			return _t.end();
		}
		bool Insert(const K& k)//将数值增添到红黑树
		{
			return _t.Insert(k); 
		}
	private:
		RBTree<K, K, SetKeyOfT> _t;//传K和用于判断的类
	};
}

红黑树的改动:

template<class T>//从K,V改为T
class RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;

	T _kv;

	Colour _col;//记录是红色还是黑色

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

template<class T>
class __TreeIterator//迭代器
{
	typedef RBTreeNode<T> Node;
	typedef __treeIterator<T> Self;

	Node* _node;

	T& operator*()//重载 *
	{
		return _node->_kv;
	}

	T& operator->()//重载 ->
	{
		return &_node->_kv;
	}

	Self& operator++()//重载++(也就是中序遍历)
	{
		if (_node->_right)
		{
			Node* subLeft = _node->_right;
			while (subleft->_left)
			{
				subLeft = subLeft->_left;
			}
			_node = subLeft;
		}
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent&&cur==parent->_right)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}
	Self& operator--()
	{
		return *this;
	}
	operator!=(const Selft& s)
	{
		return _node != s->_node;
	}
};

template<class K,class T,class KOfT>//K==key,T==Key or pair<K,V>,KOfT==SetKeyOfT or MapKeyOfT
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef __TreeIterator<T> iterator;
	iterator begin()//中序遍历,找到最左的节点
	{
		Node* cur = _root;
		while (cur && cur->_left)
		{
			cur = cur->_left;
		}
		return iterator(cur);
	}
	iterator end()//end()不存在也就是最右的nullptr,直接写nullptr也是一样
	{
		return iterator(nullptr);
	}
private:
  RBTreeNode* _root;
};

 模板关系


 operator++

Self& operator++()
	{
		if (_node->_right)//该节点存在右节点
		{
			Node* subLeft = _node->_right;
			while (subleft->_left)//找到最左节点
			{
				subLeft = subLeft->_left;
			}
			_node = subLeft;
		}
		else//右节点为nullptr(完成了一次遍历),找到下一个父节点
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent&&cur==parent->_right)//走出连续的右节点
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}

结束,我没写operator--,自己试试吧

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值