map和set的底层实现

前言

map和set的底层都是由红黑树构成,但是map是kv模型,set是k模型。如何用一颗子树来同时封装map和set,还有怎么实现map/set的迭代器是这节重点

map和set的模板参数

struct MapKeyOfT
		{
			const K& operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
private:
		RBTree<K, pair<K, V>, MapKeyOfT> _t;
struct SetKeyOfT
		{
			const K& operator()(const K& k)
			{
				return k;
			}
		};
private:
		RBTree<K, K, SetKeyOfT> _t;
template<class K, class T, class KeyOfT>

我们通过在红黑树模板中增加一个KeyOfT参数,通过map和set的模板来识别是

map还是set

这样后面的数据就要通过KeyOfT形成的对象来比较大小了

如·:查找函数

//查找函数
iterator Find(const K& key)
{
	KeyOfT kot;
	Node* cur = _root;
	while (cur)
	{
		if (key < kot(cur->_data)) //key值小于该结点的值
		{
			cur = cur->_left; //在该结点的左子树当中查找
		}
		else if (key > kot(cur->_data)) //key值大于该结点的值
		{
			cur = cur->_right; //在该结点的右子树当中查找
		}
		else //找到了目标结点
		{
			return iterator(cur); //返回该结点
		}
	}
	return end(); //查找失败
}

迭代器

struct  _TreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef _TreeIterator<T,Ptr,Ref> Self;
	typedef _TreeIterator<T, T*, T&> iterator;
};
//构造函数
__TreeIterator(Node* node)
	:_node(node) //根据所给结点指针构造一个正向迭代器
{}

++运算符重载

1,右子树不为空,访问右子树的最左节点

2,右子树为空,找到该节点父亲,向上更新

Self& operator++()
    {
        if (_node->_right)
        {
            Node* min = _node;
            while (min)
            {
                min = min->_left;
            }
            _node = min;
        }
        else
        {
            Node* cur = _node;
            Node* parent = cur->_parent;
            while (parent && parent->_right == cur)
            {
                cur = cur->_parent;
                parent = parent->_parent;
            }
            _node = parent;
        }
        return *this;
    }

--运算符重载

 Self& operator--()
    {
        if (_node->_left)
        {
            Node* max = _node->_left;
            while (max->_right)
            {
                max=max->_right
            }
            _node = max;
        }
        else
        {
            Node* cur = _node;
            Node* parent = cur->_parent;
            if (parent&&cur == parent->_left)
            {
                cur = parent;
                parent = parent->_parent;
            }
            _node = parent;
        }
        return *this;
    }

迭代器总代码

template<class T,class Ref,class Ptr>
struct RBTreeIterator
{
    typedef RBTreeNode<T> Node;
    typedef RBTreeIterator<T,Ref, Ptr> Self;
    Node* _node;
    RBTreeIterator(Node* node)
        :_node(node)
    {}
    Ref operator*()
    {
        return _node->_data;
    }
    Ptr operator->()
    {
        return &_node->_data;
    
    }
   
    Self& operator++()
    {
        if (_node->_right)
        {
            Node* min = _node;
            while (min)
            {
                min = min->_left;
            }
            _node = min;
        }
        else
        {
            Node* cur = _node;
            Node* parent = cur->_parent;
            while (parent && parent->_right == cur)
            {
                cur = cur->_parent;
                parent = parent->_parent;
            }
            _node = parent;
        }
        return *this;
    }
    bool operator!=(const Self& s) 
    {
        return _node != s._node;
    }
    bool operator==(const Self& s) const
    {
        return _node == s._node;
    }
    Self& operator--()
    {
        if (_node->_left)
        {
            Node* max = _node->_left;
            while (max->_right)
            {
                max=max->_right
            }
            _node = max;
        }
        else
        {
            Node* cur = _node;
            Node* parent = cur->_parent;
            if (parent&&cur == parent->_left)
            {
                cur = parent;
                parent = parent->_parent;
            }
            _node = parent;
        }
        return *this;
    }
};

RBTree代码实现(重点更改部分)

begin()和end()

  typedef RBTreeIterator<T, T&, T*> iterator;
    iterator begin()
    {
        Node* min = _root;
        while (min&&min->_left)
        {
            min = min->_left;
        }
        return iterator(min);
    }
    iterator end()
    {
        return iterator(nullptr);
    }

构造函数/析构函数

RBTree()
        :_root(nullptr)
    {}
    ~RBTree()
    {
        Destory(root);
        _root = nullptr;
    }
    void Destory(Node* root)
    {
        if (root == nullptr)
        {
            return;
        }
        Destory(root->_left);
        Destory(root->_right);
        delete root;
    }

析构函数是递归进行删除的

拷贝构造/赋值重载

    RBTree<K, T, KeyOfT>& operator=(RBTree<K, T, KeyOfT> t)
    {
        swap(_root, t._root);
        return *this;
    }
    RBTRee(const RBTree<K, T, KeyOfT>& t)
    {
        _root = Copy(t._root);
    }
    void* Copy(Node* root)
    {
        if (root == nullptr)
        {
            return nullptr;
        }
        Node* newroot = new Node(*root);
        newroot->_col = root->_col;
        newroot->_left = Copy(root->_left);
        newroot->_right = Copy(root->_right);
        if (newroot->_left)
        {
            newroot->_left->_parent = newroot;
        }
        if (newroot->_right)
        {
            newroot->_right->_parent = newroot;
        }
        return newroot; 
    }

赋值重载利用现代写法

拷贝构造是递归进行拷贝的,由于只拷贝了节点,所以还要自己手动去链接父节点

插入函数的修改

插入函数修改成

  pair<iterator,bool> Insert(const T& data)

返回值为

 return make_pair(iterator(newnode), true);

、因为map中【】的本质就是调用insert函数,而【】在map中有多种功能:1:如果存在,返回value值2:如果不存在,则插入新节点

map/set都返回pair结构,其中map返回pair中的k值,set返回k值

set类

#pragma once

#include"RBTree.h"

namespace muyu
{

	template<class K>
	class set
	{
		struct SetofT
		{
			const K& operator()(const K& data)
			{
				return data;
			}
		};

	public:
		typedef typename RBTree<K, K, SetofT>::const_iterator iterator;
		typedef typename RBTree<K, K, SetofT>::const_iterator const_iterator;


	public:
		pair<iterator, bool>& insert(const K& data)
		{
			pair<RBTree<K, K, SetofT>::iterator, bool> tem = _t.Insert(data);
			pair<iterator, bool> res = tem;
			return res;
		}

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

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

		iterator find(const K& key)
		{
			return _t.find(key);
		}

	private:
		RBTree<K, K, SetofT> _t;
	};
}

map类

#pragma once

#include"RBTree.h"

namespace muyu
{

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


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

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

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

		const_iterator begin()const
		{
			return _t.begin();
		}
		
		iterator find(const K& key)
		{
			return _t.find(key);
		}
		
		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;
		}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值