C++: 红黑树迭代器,map和set的封装

(一)红黑树定义

红黑树的定义:

enum Colour
{
	RED,
	BLACK
};

template<class T>
struct RBTreeNode
{
	// 这里更新控制平衡也要加入parent指针
	T _data;
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	Colour _col;


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

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();


	Iterator end();
	

	const_Iterator begin() const;
	

	const_Iterator end() const;
	
	pair<Iterator, bool> Insert(const T& data);


private:
	Node* _root = nullptr;
};

这里需要对Insert进行说明:

        Insert返回的是pair<Iterator, bool>

        若插入时存在该插入的data时,返回已存在结点的iterator和false。

        若插入时不存在该data,则返回该新插入结点的iterator和true;

(二)红黑树的迭代器

红黑树迭代器的定义:

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

	Node* _node;

  //构造函数,或者是拷贝构造,具体看实例化的对象是什么类型
	RBTreeIterator(const Iterator& it)
		:_node(it._node)
	{}

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

	Self& operator++();
	

	Self& operator--();

	
	T& operator*();

	T* operator->();
	
	bool operator!=(const Self& s)const;

	bool operator==(const Self& s)const;
	
};

1.operator++ 以及 oprator --

operator++ (按中序遍历):

        若  原结点的右子树不为空,则访问该右树的最左结点;

        若  原结点的右子树为空,则this这棵树访问完了,这就需要向上一级的子树移动,继续判断,这是一个循环的过程:只要当前节点是父节点的右子树根节点,则表示以父为根的子树访问完了,需要向上一级子树移动。直到当前结点为父节点的左孩子时停止访问(当前结点就是我们要的)。

Self& operator++()
{
    //右边不为空
	if (_node->_right)
	{
		Node* sub = _node->_right;
		while (sub->_left)
		{
			sub = sub->_left;
		}

		_node = sub;
	}
	else   //右边为空
	{
		Node* cur = _node;
		Node* parent = cur->_parent;
		while (parent && cur == parent->_right)
		{
			cur = parent;
			parent = cur->_parent;
		}

		_node = parent;
	}

	return *this;
}

operator-- (按中序遍历):

        若  原结点的左子树不为空,则访问该左树的最右结点;

        若  原结点的左子树为空,则this这棵树访问完了,这就需要向上一级的子树移动,继续判断,这是一个循环的过程:只要当前节点是父节点的左子树根节点,则表示以父为根的子树访问完了,需要向上一级子树移动。直到当前结点为父节点的右孩子时停止访问(当前结点就是我们要的)。

Self& operator--()
{
	if (_node->_left)
	{
		Node* sub = _node->_left;
		while (sub->_right)
		{
			sub = sub->_right;
		}

		_node = sub;

	}
	else
	{
		Node* cur = _node;
		Node parent = cur->_parent;
		while (parent && cur == parent->_left)
		{
			cur = parent;
			parent = cur->_parent;
		}

		_node = parent;

	}
	return *this;
}

 

(三)map的封装

map的底层结构就是红黑树,因此在map中直接封装一棵红黑树,然后将其接口包装下即可

但是需要提供一个MapkeyofT类型,用于得到key,需要给红黑树进行插入时能得到key进行比较。

namespace xrw
{
	template<class K, class V>
	class map
	{
		struct MapKeyOfT
		{
			const K& operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
		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();
		}

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

		pair<iterator, bool> insert(const pair<K, V>& kv)
		{
			return _t.Insert(kv);
		}

	private:
		RBTree<K, pair<const K, V>, MapKeyOfT> _t;
	};
}

map的红黑树成员的类型 :

RBTree<K, pair<const K, V>, MapKeyOfT> _t;

这里的是pair<const K, V>,因为在map中k的值不能改变,但value的值确是可以的,用上面这种方式控制红黑树类型非常巧妙,方便。

(四)set的封装 

同样的set的底层结构就是红黑树,因此在map中直接封装一棵红黑树,然后将其接口包装下即可

但是需要提供一个MapkeyofT类型,用于得到key,需要给红黑树进行插入时能得到key进行比较。

namespace xrw
{
	template<class K>
	class set
	{
		struct SetKeyOfT
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	public:
		typedef typename RBTree<K, K, SetKeyOfT>::const_Iterator iterator;
		typedef typename RBTree<K, K, SetKeyOfT>::const_Iterator const_iterator;

		const_iterator begin() const
		{
			return _t.begin();
		}

		const_iterator end() const
		{
			return _t.end();
		}

		// iterator RBTree::const_iterator
		pair<iterator, bool> insert(const K& key)
		{
			// pair<RBTree::iterator, bool>
			//在底层红黑树中,调用insert会返回普通迭代器,所以此时需要将迭代器变成const类型的
			pair<typename RBTree<K, K, SetKeyOfT>::Iterator, bool> ret = _t.Insert(key);
			return pair<iterator, bool>(ret.first, ret.second);
        //此处的会调用迭代器的构造函数,用于返回const的迭代器
		}
	private:
		RBTree<K, K, SetKeyOfT> _t;
	};
}

set的迭代器所指向的都是红黑树的const迭代器。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值