用于在O(1)中搜索关键字并在O(1)中获取最大值的键值数据结构

时间:2013-01-23 00:33:32

标签: c++ boost data-structures stl bimap

我需要实现一个键值数据结构,在O(lgn)或O(1)中搜索唯一的,并在O中获得max ( 1)。我正在考虑

boost::bimap< unordered_set_of<key> ,multiset_of<value> >

请注意,我的键值数据集中没有重复的键。但是,两个键可能具有相同的值。因此我使用multiset来存储值。

我需要经常插入/删除/更新键值对

听起来如何?

2 个答案:

答案 0 :(得分:2)

这取决于你想做什么。因此很明显,您希望将它用于迭代中的一些最大值迭代构造。

问题1:您是否也通过访问元素?

  • 如果,我可以为您考虑两种解决方案:

    1. 使用boost::bimap - 具有对数运行时的简单,经过测试的解决方案。

    2. 创建一个自定义容器,其中包含std::map(或者更快的按键访问std::unordered_map)和堆实现(例如std::priority_queue<std::map<key, value>::iterator> +自定义比较器),让它们保持同步等等。这是艰难的方式,但也许更快。两者上的大多数操作都是O(logn)(插入,获取和弹出最大,按键获取,删除),但常量有时很重要。虽然您使用std::unordered_map,但按键操作的访问将是O(1)。

      您可能还想为新容器编写测试,并针对您最常使用的操作进行优化。

  • 如果没有,您实际上只是使用最大值来访问元素

    问题2:你是随机插入/删除/更新元素还是首先在一轮中放入所有元素然后逐个删除它们?

    • 用于随机插入/删除/更新使用std::priority_queue<std::pair<value, key>>

    • 如果先放入元素,然后逐个删除它们,请在第一次删除操作之前使用std::vector<std::pair<value, key>>std::sort()。实际上不要删除元素,只需迭代它们。

答案 1 :(得分:1)

您可以使用std::mapstd::set来构建此内容。

  1. 一个用于保存实际值的地图,即std::map<key, value> m;。这是存储值的位置。将元素插入地图是O(log n)。

  2. 一组指向地图的迭代器;这个集合按照相应地图条目的值排序,即std::set<std::map<key, value>::iterator, CompareBySecondField> s;类似(未经测试):

    template <class It>
    struct CompareBySecondField : std::binary_function<It, It, bool> {
        bool operator() ( const T &lhs, const T &rhs ) const {
            return lhs->second > rhs->second;
        }
    };
    

    然后,您可以使用*s.begin();获取具有最大值的地图条目的迭代器。

  3. 这很容易构建,但每次添加/删除元素时都必须确保更新两个容器。