从零开始手写STL库:multiset

从零开始手写STL库–multiset的实现

Gihub链接:miniSTL



一、multiset是什么

multiset 是一个有序容器,允许存储多个相同的元素,并按照元素的值进行排序,以红黑树为基础构建。

与set的区别在于,它允许储存重复的元素,而set的元素都是独一无二的。

但是红黑树里面是不允许重复元素的,那要怎么实现这个multiset呢?

实际上multiset并不会真的插入好几个一样的元素,没必要,而且会影响搜索

multiset的红黑树节点会额外的包含一个元素:count

用count的加减来表示元素是否重复,如果插入重复元素,那只需要对conut++即可

二、multiset要包含什么函数

依然是插入删除查找三个函数,不过插入和删除需要注意重复元素的判断

    void insert(const Key &key) 
    {
        auto count = rbTree.at(key);
        if (count != nullptr) 
        {
            (*count)++;
            sz++;

            return;
        }
        rbTree.insert(key, 1);
        sz++;
    }

    void erase(const Key &key) 
    {
        auto count = rbTree.at(key);
        if (count == nullptr) 
        {
            return;
        }

        (*count)--;
        sz--;
        if (*count == 0) 
        {
            rbTree.remove(key);
        }
    }

只有当节点不存在时才插入,只有当节点数只有一时才删除

其他功能就是正常的输出

template<typename Key>
class myMultiSet
{
private:
    myRedBlackTree<Key, size_t> rbtree;
    size_t sz;

public:
    myMultiSet() : sz(0) {}
    ~myMultiSet() {}

    void insert(const Key &key) 
    {
        auto count = rbTree.at(key);
        if (count != nullptr) 
        {
            (*count)++;
            sz++;

            return;
        }
        rbTree.insert(key, 1);
        sz++;
    }

    void erase(const Key &key) 
    {
        auto count = rbTree.at(key);
        if (count == nullptr) 
        {
            return;
        }

        (*count)--;
        sz--;
        if (*count == 0) 
        {
            rbTree.remove(key);
        }
    }

    size_t size() const { return sz; }
    bool empty() const { return sz == 0; }

    size_t count(const Key &key) 
    {
        auto num = rbTree.at(key);
        if (num != nullptr) 
        {
            return *num;
        }

        return 0;
    }

    void clear() 
    {
        sz = 0;
        rbTree.clear();
    }    
};

总结

只需要注意重复元素的处理方式即可,也就是用另外的count去记录,而不是真的插入多个相同元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值