1

我正在寻找一种可以保持其元素排序的良好数据结构。目前我正在尝试Boost.Heap

我经常需要有序地遍历数据结构,并在到达基于某些属性的元素时,更新其优先级。Boost.Heap 优先级队列提供有序和无序迭代器。元素更新通过节点句柄发生,句柄可以从普通的无序迭代器中获取,但不能直接从有序迭代器中获取,如下例所示:

#include <iostream>
#include <algorithm>
#include <boost/heap/fibonacci_heap.hpp>

using namespace boost::heap;

int main()
{
    fibonacci_heap<int> fib_heap;

    fib_heap.push(1);
    fib_heap.push(2);
    fib_heap.push(3);

    for(auto i = fib_heap.ordered_begin(); i != fib_heap.ordered_end(); ++i)
    {
        // no viable conversion here
        auto h = fibonacci_heap<int>::s_handle_from_iterator(i);

        if(*h == 2) // dumb test
        {
            fib_heap.increase(h, *h + 2);
            break;
        }
    }

    std::for_each(fib_heap.ordered_begin(), fib_heap.ordered_end(),
    [](const int &e)
    {
        std::cout << e << std::endl;
    });
}

如何有序地遍历队列并更新遍历中的元素?

请注意,我在更新后离开了遍历。

(欢迎为此目的提供替代库的建议)

4

2 回答 2

1

如果找不到更好的选择,我需要将句柄保存在每个相应元素内以供以后使用(c++1y 代码):

#include <iostream>
#include <algorithm>
#include <boost/heap/fibonacci_heap.hpp>

using namespace boost::heap;

template<typename T>
struct heap_data
{
    typedef typename fibonacci_heap<heap_data>::handle_type handle_t;
    handle_t handle;
    T data;

    heap_data(const T &data_) : data(data_) {}

    bool operator<(heap_data const & rhs) const
    {
        return data < rhs.data;
    }
};

void setup_handle(fibonacci_heap<heap_data<int>>::handle_type &&handle)
{
    (*handle).handle = handle;
}

int main()
{
    fibonacci_heap<heap_data<int>> heap;

    setup_handle(heap.emplace(1));
    setup_handle(heap.emplace(2));
    setup_handle(heap.emplace(3));

    std::find_if(heap.ordered_begin(), heap.ordered_end(),
    [&heap](const heap_data<int> &e)
    {
        if(e.data == 2)
        {
            const_cast<heap_data<int> &>(e).data += 2;
            heap.increase(e.handle);
            return true;
        }
        return false;
    });

    std::for_each(heap.ordered_begin(), heap.ordered_end(),
    [](const heap_data<int> &e)
    {
        std::cout << e.data << std::endl;
    });
}
于 2013-02-27T04:35:47.303 回答
0

你的要求对我来说不是很清楚。但是 std::multimap 或 std::multiset 怎么样?更新操作是 O(log n)。我认为遍历应该是 O(n)(BST 遍历),但它没有记录在我的标准 C++ 参考(cppreference.com、cplusplus.com)中。看起来boost::heap 遍历是摊销的 O(n log n)。

于 2013-03-01T08:01:02.343 回答