【问题标题】:Breadth First Search (BFS)广度优先搜索 (BFS)
【发布时间】:2020-01-15 15:45:16
【问题描述】:

我正在研究 BFS 算法,但我有一个关于如何将相邻节点插入队列的问题。

例如,假设我们正在处理一个无向图,并且我们想要执行 BFS 以输出图的内容,那么我们如何知道相邻节点插入到哪个 order从队列中拉出初始节点后的队列?另外,有没有办法修改相邻节点插入队列的方式?

任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 答案将部分取决于节点是邻居这一事实的表示方式。并且根据 BFS 算法的实现,邻居的顺序可能很重要,也可能无关紧要。
  • 在许多情况下,顺序没有区别。

标签: java algorithm traversal breadth-first-search


【解决方案1】:

兄弟(邻居)的插入顺序完全由插入它们的代码决定——从理论上讲,没有要求。 BFS 的要求是在深度为k 的所有节点之前遍历所有深度为k+1 的节点。

例如,给定队列q和根节点root

q.enqueue(root);

while(!q.isEmpty()) {
     Node n = q.dequeue();

     <process n>

     // add children to queue
     for (Node child : n.getChildren()) {
          q.enqueue(child);
     }
}

所以如果这以n 作为树的根开始,它将按级别顺序遍历整个树,即广度优先。所以你问,孩子是按什么顺序插入的?好吧,这仅取决于 getChildren() 遍历节点的顺序(在此示例中)。其他实现可能会对它们进行排序并按该顺序添加它们。或者有一个父级下的子级的链表顺序。或者随意挑选。

如果节点有数值并且树有格式

1
1.1 1.2          1.3
    1.2.1 1.2.2  1.3.1

代码可以设置为按数字顺序遍历子项。它将处理 1,将其子代 (1.1, 1.2, 1.3) 添加到队列中,处理 1.1,将其子代 (none) 添加到队列中,处理 1.2,将其子代 (1.2.1, 1.2.2) 添加到队列中,进程 1.3 及其子进程 (1.3.1) 到队列中,然后进入第三级。

如果您想修改顺序,您可以 (A) 更改将节点添加到队列的代码逻辑,指定选择下一个要推送的子节点的特定方式,而不是盲目地迭代,(B) 更改/覆盖 enquque 块调用的迭代函数getChildren(),或 (C) 如果您知道迭代方法但无法更改代码,则强制树具有将由迭代函数以如下方式遍历的设置例如,通过重命名节点或以特定方式将它们链接到结构中。选项 (B) 可能是首选。

既然您说图形是“无向的”,听起来您可能无法控制图形本身的顺序,因此选项(C)无论如何都不起作用。因此,如果要控制子节点的顺序,则需要使迭代代码以某种方式对节点进行排序,以便获得一致的结果。

【讨论】:

  • 为了增加一个实用的角度,该图很可能使用标准数据结构来表示,例如邻接表(在这种情况下,邻居将按照它们作为邻居添加到当前的任何顺序进行迭代节点),邻接矩阵(在这种情况下,邻居可能会按数字升序迭代),或边缘列表(在这种情况下,邻居将按照添加边缘的顺序进行迭代)。如果邻接列表或边缘列表数据结构使用集合而不是列表,则可能未指定顺序。
猜你喜欢
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多