我正在尝试使用以下伪代码在Java中实现BFS算法:
1. for each vertex u ∈ G.V - {s} // for each vertex except for the source
2. u.color = WHITE // (line 1 cont) in the graph
3. u.distance = ∞
4. u.parent = NIL
5. source.color = GRAY
6. source.distance = 0
7. source.parent = NIL
8. Q = Ø
9. Enqueue (Q, source)
10. while Q != Ø
11. u = Dequeue(Q)
12. for each v ∈ G.Adj[u] // for each adjacent vertext
13. if v.color == WHITE
14. v.color = GRAY
15. v.distance = u.distance + 1
16. v.parent = u
17. Enqueue(Q, v)
18. u.color = BLACK
颜色代表每次访问该节点的时间:
WHITE = 2 未发现
GRAY = 3 ,但尚未发现其所有相邻邻居
BLACK = 4 ,发现了所有相邻邻居,无需返回此处
u.distance表示从节点到源节点的距离,而u.parent是指向源节点的父节点
我的教授说,与其为每个节点(u.color,u.d,u.pi)创建一个对象,不如为每个节点使用一个数组来存储每个节点的值。
他还向我们提供了框架代码,其中包括用于对其进行测试的邻接矩阵。
-
我目前正在努力处理第11行和第12行(我认为)。我能够创建和初始化所有数组以及队列,但是在实现 queue.poll()或 queue.remove()函数时遇到了麻烦第11行按我的预期行事。我也不知道我是否正确创建了for循环。
我尝试使用从LinkedList和Queue导入的.poll()和.remove()函数。 这应该做的是删除队列的开头并将其值分配给变量u,否?
当我运行代码时,第17行会添加到队列中,但是队列的头部永远不会在下一次迭代中删除,而第18行只会在第一次迭代(源节点)上执行。
strong>我不确定是否正确地实现了伪代码的第12行,因为我正在使用普通的for循环(int v; v 我尝试一路打印出数组,以查看for循环的运行方式。使用此代码,我可以看到在第一次迭代之后,头部并没有从队列中移出并分配给值u。 这是要对其进行测试的矩阵: 我的结果: 我希望它最终会像下面这样:while (!q.isEmpty())
{
u = q.poll(); // sets value of u... to most recent item removed from queue??
for (v = 0; v < colors.length; v++)
{
if (colors[v] == WHITE)
{
colors[v] = GRAY; // Sets color of VISITED Node to
dist[v] = dist[u] + 1; // sets distance at index v to value of the index most recently removed from queue + 1
parent[v] = u; // sets parent of index v to most recently removed item from queue
q.add(v); // adds node V to the queue
}
}
colors[u] = BLACK; // sets color of node to black (node visited + adjacent nodes visited)
}
return dist; // returns distance array
}
int n = 8;
int[][] A =
{{0, 1, 0, 0, 1, 0, 0, 0},
{1, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 1, 1, 0},
{0, 0, 1, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 0, 0, 0, 1, 0},
{0, 0, 1, 1, 0, 1, 0, 1},
{0, 0, 0, 1, 0, 0, 1, 0}};
COLORS: [2, 3, 2, 2, 2, 2, 2, 2]
DISTANCE: [2147483647, 0, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647]
PARENT: [0, 0, 0, 0, 0, 0, 0, 0]
COLORS: [3, 3, 2, 2, 2, 2, 2, 2]
dist[u] = 0
DISTANCE: [1, 0, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647]
PARENT: [1, 0, 0, 0, 0, 0, 0, 0]
QUEUE: []
COLORS: [3, 3, 3, 2, 2, 2, 2, 2]
dist[u] = 0
DISTANCE: [1, 0, 1, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647]
PARENT: [1, 0, 1, 0, 0, 0, 0, 0]
QUEUE: [0]
COLORS: [3, 3, 3, 3, 2, 2, 2, 2]
dist[u] = 0
DISTANCE: [1, 0, 1, 1, 2147483647, 2147483647, 2147483647, 2147483647]
PARENT: [1, 0, 1, 1, 0, 0, 0, 0]
QUEUE: [0, 2]
COLORS: [3, 3, 3, 3, 3, 2, 2, 2]
dist[u] = 0
DISTANCE: [1, 0, 1, 1, 1, 2147483647, 2147483647, 2147483647]
PARENT: [1, 0, 1, 1, 1, 0, 0, 0]
QUEUE: [0, 2, 3]
COLORS: [3, 3, 3, 3, 3, 3, 2, 2]
dist[u] = 0
DISTANCE: [1, 0, 1, 1, 1, 1, 2147483647, 2147483647]
PARENT: [1, 0, 1, 1, 1, 1, 0, 0]
QUEUE: [0, 2, 3, 4]
COLORS: [3, 3, 3, 3, 3, 3, 3, 2]
dist[u] = 0
DISTANCE: [1, 0, 1, 1, 1, 1, 1, 2147483647]
PARENT: [1, 0, 1, 1, 1, 1, 1, 0]
QUEUE: [0, 2, 3, 4, 5]
COLORS: [3, 3, 3, 3, 3, 3, 3, 3]
dist[u] = 0
DISTANCE: [1, 0, 1, 1, 1, 1, 1, 1]
PARENT: [1, 0, 1, 1, 1, 1, 1, 1]
QUEUE: [0, 2, 3, 4, 5, 6]
COLORS: [4, 4, 4, 4, 4, 4, 4, 4]
dist[u] = most recently removed from queue (not 0)
DISTANCE: [1, 0, 2, 3, 2, 1, 2, 3]
QUEUE: []
答案 0 :(得分:0)
while循环内的for循环不正确。由于给定了邻接矩阵表示形式,因此让Graph [] []作为矩阵,您将具有以下属性。
Graph [i] [j] == 0,在顶点i和j之间没有边; Graph [i] [j] == 1,在顶点i和j之间有一条边;
假设您有n个顶点,则for循环应为:
for(int i = 0; i < n; i++) {
if(Graph[u][i] == 1) {
//put in the color/distance updates here
}
}
您提到的其他示例(整数v:graph.adj [u])是图的邻接表表示。