我正在寻找一个可以维护其元素排序的良好数据结构。目前我正在尝试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;
});
}
如何有序地遍历队列并更新遍历中的元素?
请注意,我在更新后会离开遍历。
(欢迎为此目的提供替代图书馆的建议)
答案 0 :(得分: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;
});
}
答案 1 :(得分:0)
您的要求对我来说不是很清楚。但是std :: multimap或std :: multiset怎么样?更新操作是O(log n)。我认为遍历应该是O(n)(BST traversal),但我的标准C ++引用(cppreference.com,cplusplus.com)中没有记录。看似boost::heap traversal的摊销是O(n log n)。