在图类中,我需要处理具有整数值的节点(主要是1-1000)。在每个步骤中,我想从图中删除节点及其所有邻居。另外,我想始终以最小值的节点开始。我很想过如何以最快的方式做到这一点,并决定做以下事情:
std::vector<Node*> bucket[1000]
来存储节点的值对此有更有效的方法吗?
我想过使用类似std::list<Node*> bucket[1000]
的东西,并为每个节点分配一个指向其&#34; list元素&#34;的指针,这样我就可以从O(1)中的列表中删除该节点。使用stl列表是否可以实现这一点,显然可以使用普通的双链表来完成,我可以手工实现吗?
答案 0 :(得分:1)
我最近为使用存储桶的优先级队列实现做了类似的事情。
我所做的是使用哈希表(unordered_map),这样,你不需要存储1000个空向量,你仍然可以获得O(1)随机访问(一般情况下,不保证)。现在,如果您只需要存储/创建此图表类一次,它可能无关紧要。在我的情况下,我需要创建每秒数十/数百个时间的优先级队列并使用哈希映射产生巨大的差异(由于我实际上有一个优先级元素时我只创建了无序的事实,所以不需要初始化1000个空哈希集)。散列集和映射是C ++ 11中的新增功能,但现在已经在std :: tr1中使用了一段时间,或者您可以使用Boost库。
我和你之间可以看到的唯一区别我的用例,就是你还需要能够删除相邻节点。我假设每个节点都包含一个指向它的邻居的指针列表。如果是这样,删除邻居应该k * O(1)
k
邻居的数量(一般来说,O(1),不保证,最坏的情况是unordered_map / set中的O(n)) 。您只需遍历每个相邻节点,获取其优先级,即可为哈希映射提供正确的索引。然后你找到优先级映射到的哈希集中的指针,这个搜索通常是O(1),一般来说,删除元素也是O(1)。
总而言之,我认为你很清楚要做什么,但我相信使用哈希映射/设置会使你的代码加速很多(取决于当然的确切用法)。对我而言,unordered_map<int, unordered_set>
与vector<set>
的实施速度提升约为50倍。
答案 1 :(得分:1)
这是我要做的。节点结构:
struct Node {
std::vector<Node*>::const_iterator first_neighbor;
std::vector<Node*>::const_iterator last_neighbor;
int value;
bool deleted;
};
连接邻接列表并将它们放在一个std::vector<Node*>
中以降低内存管理的开销。我使用软删除功能,因此更新速度并不重要。
按值将节点的指针排序到具有counting sort的另一个std::vector<Node*>
。将所有节点标记为未删除。
按排序顺序迭代节点。如果已删除所考虑的节点,请转到下一个节点。否则,将其标记为已删除并迭代其邻居并将其标记为已删除。
如果您的节点连续存储在内存中,那么您可以在结构末尾以额外的Sentinel节点为代价省略last_neighbor
,因为节点的last_neighbor
为first_neighbor
后续节点。