Skip to content

Instantly share code, notes, and snippets.

@relaxnow
Created September 1, 2012 00:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save relaxnow/3561624 to your computer and use it in GitHub Desktop.
Save relaxnow/3561624 to your computer and use it in GitHub Desktop.
Topological sorting with directed cycle detection
<?php
$a = new Node('a');
$b = new Node('b');
$c = new Node('c');
$d = new Node('d');
$e = new Node('e');
$a->dependsOn($b);
$a->dependsOn($d);
$b->dependsOn($c);
$b->dependsOn($e);
$c->dependsOn($d);
$c->dependsOn($e);
$d->dependsOn($b);
$resolved = resolveDependency($a);
foreach ($resolved as $resolvedNode) {
echo $resolvedNode->getName() . PHP_EOL;
}
function resolveDependency(Node $node, &$resolved = array(), &$seen = array()) {
$seen[] = $node;
foreach ($node->getEdges() as $edge) {
if (!in_array($edge, $resolved)) {
if (!in_array($node, $seen)) {
resolveDependency($edge, $resolved);
}
else {
throw new RuntimeException('Circular reference detected!');
}
}
}
$resolved[] = $node;
return $resolved;
}
class Node
{
private $name;
private $edges = array();
public function __construct($name)
{
$this->name = $name;
}
public function dependsOn(Node $node)
{
$this->edges[] = $node;
}
public function getName()
{
return $this->name;
}
public function getEdges()
{
return $this->edges;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment