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

(一)红黑树定义

红黑树的定义:

enum Colour
{
	RED,
	BLACK
};

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


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

template
class RBTree
{
	typedef RBTreeNode Node;
public:
	typedef RBTreeIterator Iterator;
	typedef RBTreeIterator const_Iterator;

	Iterator begin();


	Iterator end();
	

	const_Iterator begin() const;
	

	const_Iterator end() const;
	
	pair Insert(const T& data);


private:
	Node* _root = nullptr;
};

这里需要对Insert进行说明:

        Insert返回的是pair

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

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

(二)红黑树的迭代器

红黑树迭代器的定义:

template
struct RBTreeIterator
{
	typedef RBTreeNode Node;
	typedef RBTreeIterator Iterator;
	typedef RBTreeIterator 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 map
	{
		struct MapKeyOfT
		{
			const K& operator()(const pair& kv)
			{
				return kv.first;
			}
		};
	public:
		typedef typename RBTree, MapKeyOfT>::Iterator iterator;
		typedef typename RBTree, 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 ret = insert(make_pair(key, V()));
			return ret.first->second;
		}

		pair insert(const pair& kv)
		{
			return _t.Insert(kv);
		}

	private:
		RBTree, MapKeyOfT> _t;
	};
}

map的红黑树成员的类型 :

RBTree, MapKeyOfT> _t;

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

(四)set的封装 

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

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

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

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

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

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

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

你可能感兴趣的:(c++)