Skip to content

Commit 203ce7b

Browse files
committed
Properly stop recursion and only check in isTree()
1 parent ab1bbdb commit 203ce7b

File tree

1 file changed

+49
-39
lines changed

1 file changed

+49
-39
lines changed

src/Tree/BaseDirected.php

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,16 @@ abstract class BaseDirected extends Tree
1818
* get root vertex for this in-tree
1919
*
2020
* @return Vertex
21-
* @throws UnderflowException if given graph is empty
22-
* @throws UnexpectedValueException if given graph is not a tree
21+
* @throws UnderflowException if given graph is empty or no possible root candidate was found (check isTree()!)
2322
*/
2423
public function getVertexRoot()
2524
{
26-
$root = $this->getVertexPossibleRoot();
27-
28-
if (count($this->getVerticesSubtree($root)) !== $this->graph->getNumberOfVertices()) {
29-
throw new UnexpectedValueException();
25+
foreach ($this->graph->getVertices() as $vertex) {
26+
if ($this->isVertexPossibleRoot($vertex)) {
27+
return $vertex;
28+
}
3029
}
31-
32-
return $root;
30+
throw new UnderflowException('No possible root found. Either empty graph or no Vertex with proper degree found.');
3331
}
3432

3533
/**
@@ -41,15 +39,25 @@ public function getVertexRoot()
4139
*/
4240
public function isTree()
4341
{
44-
if (!$this->graph->isEmpty()) {
45-
try {
46-
$this->getVertexRoot();
47-
}
48-
catch (UnexpectedValueException $e) {
49-
return false;
50-
}
42+
if ($this->graph->isEmpty()) {
43+
return true;
44+
}
45+
46+
try {
47+
$root = $this->getVertexRoot();
48+
}
49+
catch (UnderflowException $e) {
50+
return false;
51+
}
52+
53+
try {
54+
$num = count($this->getVerticesSubtree($root));
55+
}
56+
catch (UnexpectedValueException $e) {
57+
return false;
5158
}
52-
return true;
59+
60+
return ($num === $this->graph->getNumberOfVertices());
5361
}
5462

5563
/**
@@ -88,16 +96,6 @@ protected function isVertexPossibleRoot(Vertex $vertex)
8896
return (count($this->getVerticesParent($vertex)) === 0);
8997
}
9098

91-
protected function getVertexPossibleRoot()
92-
{
93-
foreach ($this->graph->getVertices() as $vertex) {
94-
if ($this->isVertexPossibleRoot($vertex)) {
95-
return $vertex;
96-
}
97-
}
98-
throw new UnderflowException('No possible root found. Either empty graph or no Vertex with proper degree found.');
99-
}
100-
10199
/**
102100
* checks if the given $vertex is a leaf (outermost vertex with no children)
103101
*
@@ -207,27 +205,39 @@ public function getHeightVertex(Vertex $vertex)
207205
* @param Vertex $vertex
208206
* @throws UnexpectedValueException if there are invalid edges (check isTree()!)
209207
* @return Vertex[]
210-
* @uses self::getVerticesChildren()
208+
* @uses self::getVerticesSubtreeRecursive()
211209
* @uses self::getVerticesSubtree()
212210
*/
213211
public function getVerticesSubtree(Vertex $vertex)
214212
{
215-
$vertices = array($vertex->getId() => $vertex);
216-
foreach ($this->getVerticesChildren($vertex) as $vid => $vertexChild) {
217-
if (isset($vertices[$vid])) {
218-
throw new UnexpectedValueException('Multiple links to child vertex found');
219-
}
220-
foreach ($this->getVerticesSubtree($vertexChild) as $vid => $vertexSub) {
221-
if (isset($vertices[$vid])) {
222-
throw new UnexpectedValueException('Multiple links to vertex found');
223-
}
224-
$vertices[$vid] = $vertexSub;
225-
}
226-
}
213+
$vertices = array();
214+
$this->getVerticesSubtreeRecursive($vertex, $vertices);
227215

228216
return $vertices;
229217
}
230218

219+
/**
220+
* helper method to get recursively get subtree for given $vertex
221+
*
222+
* @param Vertex $vertex
223+
* @param Vertex[] $vertices
224+
* @throws UnexpectedValueException if multiple links were found to the given edge (check isTree()!)
225+
* @uses self::getVerticesChildren()
226+
* @uses self::getVerticesSubtreeRecursive() to recurse into subtrees
227+
*/
228+
private function getVerticesSubtreeRecursive(Vertex $vertex, &$vertices)
229+
{
230+
$vid = $vertex->getId();
231+
if (isset($vertices[$vid])) {
232+
throw new UnexpectedValueException('Multiple links found');
233+
}
234+
$vertices[$vid] = $vertex;
235+
236+
foreach ($this->getVerticesChildren($vertex) as $vertexChild) {
237+
$this->getVerticesSubtreeRecursive($vertexChild, $vertices);
238+
}
239+
}
240+
231241
/**
232242
* get all vertices below the given $vertex (which is NOT included)
233243
*

0 commit comments

Comments
 (0)