如何实现以下算法?

时间:2013-03-07 09:33:54

标签: c++ algorithm

我很抱歉这个神秘的头衔。这是我的问题:

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()并更新它们在堆中的位置。

所以我对WikipediaBoost上的Heap数据结构做了一些浅薄的研究 问题似乎Heap似乎没有提供快速的方法来定位元素。

2。哈希表

按值对列表进行排序。构造一个哈希表,将指针Item *映射到链接列表中指向它们的迭代器。然后每次我从列表中删除顶部(最小)项时,由于哈希表,我在常量时间内找到列表中的所有邻居。然后为每个邻居recomputeValue()更新其在列表中的位置以及哈希表中的相应迭代器。

如果使用有序的跳转列表而不是链表,可能会消除对哈希表的需求。

我是编程新手,所以我的方法可能太天真和复杂,我欢迎任何建议。

总结我的问题:

  1. 有没有办法在堆中执行快速查找以使#1可行?
  2. 是否有一个容器可以维护元素的顺序并且可以执行快速查找,以便我可以使#2更清洁?
  3. 你会如何处理这个问题?

1 个答案:

答案 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 ) );
}