我正在使用STL队列在图表上实现BFS(广度优先搜索)。如果队列中不存在该节点,我需要在队列中推送一个节点。但是,STL队列执行not allow iteration through its elements因此我无法使用STL查找功能。
我可以在访问每个节点时使用一个标志来标记它们,并且只在标志为false时才推送它们,但是,我需要多次运行BFS,每次我必须重置所有标志后,所以我最终使用了一个计数器而不是一个标志,但我仍然想知道是否有一种在队列中查找项目的标准方法。
答案 0 :(得分:6)
我假设您在BFS中实施了“封闭式套装”的概念?这样做的标准方法是简单地维护已遇到的单独的std::set
或std::unordered_set
个元素。这样,您可以获得O(lg n )或O(1)查找,而在队列中进行迭代,如果支持,则需要O( n )时间。
答案 1 :(得分:-1)
公认的答案很愚蠢。
BFS搜索中的每个项目将经历三个状态:未访问,已访问但未完成,已访问。出于搜索目的,您可以将其缩小为已访问或未访问的...
您只需要使用一个标志...
标志只是交替出现。
好吧,在第一次遍历树时,每个节点将从false(未访问)开始,然后变为true(已访问)。在第二次遍历时,它将切换为true(未访问),并变为false(已访问)。
所以您要做的就是保留一个单独的标志,该标志仅在每次遍历时更改状态...
那么你的逻辑是
if ( visitedFlag ^ alternatingFlagStateOfTree )
{
visitedFlag ^= 1;
}
基本上,alternatingFlagStateOfTree仅用于指示访问状态为true还是false。每次运行都会交替进行,因此我们只需将它们交换一下。
这完全消除了对set()的需要,所有内存开销等,并且消除了在运行之间重置标志值的任何需要。
该技术可以用于更复杂的状态,只要在所遍历的所有项目之间存在一致的结束状态即可。您只需进行一些数学运算即可将标志值重置为将状态恢复为基本状态。