-
Notifications
You must be signed in to change notification settings - Fork 5
/
bfs.php
82 lines (68 loc) · 2.05 KB
/
bfs.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
/*
* A simple iterative Breadth-First Search implementation.
* http://en.wikipedia.org/wiki/Breadth-first_search
*
* 1. Start with a node, enqueue it and mark it visited.
* 2. Do this while there are nodes on the queue:
* a. dequeue next node.
* b. if it's what we want, return true!
* c. search neighbours, if they haven't been visited,
* add them to the queue and mark them visited.
* 3. If we haven't found our node, return false.
*
* @returns bool
*/
function bfs($graph, $start, $end) {
$queue = new SplQueue();
$queue->enqueue($start);
$visited = [$start];
while ($queue->count() > 0) {
$node = $queue->dequeue();
# We've found what we want
if ($node === $end) {
return true;
}
foreach ($graph[$node] as $neighbour) {
if (!in_array($neighbour, $visited)) {
# Mark neighbour visited
$visited[] = $neighbour;
# Enqueue node
$queue->enqueue($neighbour);
}
};
}
return false;
}
/*
* Same as bfs() except instead of returning a bool, it returns a path.
*
* Implemented by enqueuing a path, instead of a node, for each neighbour.
*
* @returns array or false
*/
function bfs_path($graph, $start, $end) {
$queue = new SplQueue();
# Enqueue the path
$queue->enqueue([$start]);
$visited = [$start];
while ($queue->count() > 0) {
$path = $queue->dequeue();
# Get the last node on the path
# so we can check if we're at the end
$node = $path[sizeof($path) - 1];
if ($node === $end) {
return $path;
}
foreach ($graph[$node] as $neighbour) {
if (!in_array($neighbour, $visited)) {
$visited[] = $neighbour;
# Build new path appending the neighbour then and enqueue it
$new_path = $path;
$new_path[] = $neighbour;
$queue->enqueue($new_path);
}
};
}
return false;
}