我很抱歉这个神秘的头衔。这是我的问题:
class Item
{
public:
double value;
void recomputeValue(); // after this, will probably increase a little,
// but never decrease.
std::list<Item*> neighbors; // relatively few items
};
我正在尝试实现一个过程,它会将这些项目的列表修剪为指定的大小:
void trimToNewSize(std::list<Item*>& items, int newSize);
需要实施的算法是:
while (size > newSize)
{
erase item with smallest value;
recomputeValue() for all its neighbors;
}
我已经考虑了两种方法:
1。堆
从所有值构造堆。堆很合适,因为它可以找到并删除O(1)中的最小元素,并且可以用O(n)构造。
每次删除后,找到堆中的所有邻居recomputeValue()
并更新它们在堆中的位置。
所以我对Wikipedia和Boost上的Heap数据结构做了一些浅薄的研究 问题似乎Heap似乎没有提供快速的方法来定位元素。
2。哈希表
按值对列表进行排序。构造一个哈希表,将指针Item *映射到链接列表中指向它们的迭代器。然后每次我从列表中删除顶部(最小)项时,由于哈希表,我在常量时间内找到列表中的所有邻居。然后为每个邻居recomputeValue()
更新其在列表中的位置以及哈希表中的相应迭代器。
如果使用有序的跳转列表而不是链表,可能会消除对哈希表的需求。
我是编程新手,所以我的方法可能太天真和复杂,我欢迎任何建议。
总结我的问题:
答案 0 :(得分:3)
这看起来像普通老std::map< double, Item * >
的工作。它为您提供了最小元素* items.begin()
,并且为了重新计算邻居,只需执行类似
typedef std::map< double, Item * > itemsByValue;
itemsByValue items;
class Item
{
public:
double value;
void recomputeValue(); // after this, will probably increase a little,
// but never decrease.
std::list< itemContainer::iterator > neighbors; // relatively few items
};
for ( itemsByValue::iterator i = neighbors.begin();
i != neighbors.end(); ++ i ) {
Item &item = * neighbor;
items.erase( neighbor );
item.recomputeValue();
items.insert( std::make_pair( item.value, & item ) );
}