I have a graph:
Here is a data:
$nodes = [
'f' => ['d g'],
'b' => ['a d'],
'g' => ['i'],
'd' => ['c e'],
'i' => ['h']
];
The function below trying to find a nodes between 2 provided nodes:
function findPathBetweenNodes($start, $end, $nodes) {
foreach ($nodes as $node => $edges) {
$nodes[$node] = explode(' ', $edges[0]);
}
function searchPath($current, $end, $nodes, &$visited) {
if ($current === $end) {
return [$current];
}
$visited[$current] = true;
foreach ($nodes as $node => $children) {
if (in_array($current, $children) && !isset($visited[$node])) {
$path = searchPath($node, $end, $nodes, $visited);
if ($path) {
return array_merge([$current], $path);
}
}
}
return null;
}
$visited = [];
$path = searchPath($start, $end, $nodes, $visited);
if ($path) {
array_shift($path);
array_pop($path);
}
return $path ?: [];
}
Test case: print_r(findPathBetweenNodes(‘h’, ‘f’, $nodes));
Returns correct result:
Array
(
[0] => i
[1] => g
)
Test case: print_r(findPathBetweenNodes(‘f’, ‘h’, $nodes));
Return empty array.
Test case: print_r(findPathBetweenNodes(‘a’, ‘c’, $nodes));
Returns empty array.
How to fix a function to make it work in other cases too?
Thanks.
2
Answers
The $nodes array isn’t configured as an undirected graph. The picture shown suggests it should be
For print_r(findPathBetweenNodes(‘f’, ‘h’, $nodes));
For print_r(findPathBetweenNodes(‘a’, ‘c’, $nodes));
I agree with Simon, your node relationship structure is not ideal for this task. The space-delimited values makes unnecessary extra work and cannot be optimized for searching performance. Instead, I recommend building a 2d lookup array because PHP is very fast at searching for keys (versus values searching).
In my recursive function, I included the feature of avoiding potential circular/infinite recursion by removing/consuming elements from the lookup array with each deeper traversal.
My snippet is not designed or tested to work in a scenario where multiple node paths may occur. If this is a possibility, please specify this in your question body and provide more challenging sample data (or ask a new question).
To differentiate complete/successful paths from unconnected nodes, I’ve designed my function to return
null
to indicate no qualifying path.Code: (Demo)
Output: