@@ -18,18 +18,16 @@ abstract class BaseDirected extends Tree
18
18
* get root vertex for this in-tree
19
19
*
20
20
* @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()!)
23
22
*/
24
23
public function getVertexRoot ()
25
24
{
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
+ }
30
29
}
31
-
32
- return $ root ;
30
+ throw new UnderflowException ('No possible root found. Either empty graph or no Vertex with proper degree found. ' );
33
31
}
34
32
35
33
/**
@@ -41,15 +39,25 @@ public function getVertexRoot()
41
39
*/
42
40
public function isTree ()
43
41
{
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 ;
51
58
}
52
- return true ;
59
+
60
+ return ($ num === $ this ->graph ->getNumberOfVertices ());
53
61
}
54
62
55
63
/**
@@ -88,16 +96,6 @@ protected function isVertexPossibleRoot(Vertex $vertex)
88
96
return (count ($ this ->getVerticesParent ($ vertex )) === 0 );
89
97
}
90
98
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
-
101
99
/**
102
100
* checks if the given $vertex is a leaf (outermost vertex with no children)
103
101
*
@@ -207,27 +205,39 @@ public function getHeightVertex(Vertex $vertex)
207
205
* @param Vertex $vertex
208
206
* @throws UnexpectedValueException if there are invalid edges (check isTree()!)
209
207
* @return Vertex[]
210
- * @uses self::getVerticesChildren ()
208
+ * @uses self::getVerticesSubtreeRecursive ()
211
209
* @uses self::getVerticesSubtree()
212
210
*/
213
211
public function getVerticesSubtree (Vertex $ vertex )
214
212
{
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 );
227
215
228
216
return $ vertices ;
229
217
}
230
218
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
+
231
241
/**
232
242
* get all vertices below the given $vertex (which is NOT included)
233
243
*
0 commit comments