1 package edu.uci.ics.jung.graph;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
6 import java.util.List;
7
8 import edu.uci.ics.jung.graph.util.EdgeType;
9 import edu.uci.ics.jung.graph.util.Pair;
10 import edu.uci.ics.jung.graph.util.TreeUtils;
11
12
13
14
15
16
17
18
19
20 @SuppressWarnings("serial")
21 public class DelegateForest<V,E> extends GraphDecorator<V,E> implements Forest<V,E>
22 {
23
24
25
26 public DelegateForest() {
27 this(new DirectedSparseGraph<V,E>());
28 }
29
30
31
32
33
34 public DelegateForest(DirectedGraph<V,E> delegate) {
35 super(delegate);
36 }
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 @Override
53 public boolean addEdge(E e, V v1, V v2, EdgeType edgeType) {
54 if(delegate.getVertices().contains(v1) == false) {
55 throw new IllegalArgumentException("Tree must already contain "+v1);
56 }
57 if(delegate.getVertices().contains(v2)) {
58 throw new IllegalArgumentException("Tree must not already contain "+v2);
59 }
60 return delegate.addEdge(e, v1, v2, edgeType);
61 }
62
63
64
65
66
67
68
69
70 @Override
71 public boolean addVertex(V vertex) {
72 setRoot(vertex);
73 return true;
74 }
75
76
77
78
79
80
81
82
83
84
85
86 @Override
87 public boolean removeEdge(E edge) {
88 return removeEdge(edge, true);
89 }
90
91
92
93
94
95
96
97
98
99
100
101 public boolean removeEdge(E edge, boolean remove_subtree)
102 {
103 if (!delegate.containsEdge(edge))
104 return false;
105 V child = getDest(edge);
106 if (remove_subtree)
107 return removeVertex(child);
108 else
109 {
110 delegate.removeEdge(edge);
111 return false;
112 }
113 }
114
115
116
117
118
119
120
121
122 @Override
123 public boolean removeVertex(V vertex) {
124 return removeVertex(vertex, true);
125 }
126
127
128
129
130
131
132
133
134
135
136
137
138 public boolean removeVertex(V vertex, boolean remove_subtrees)
139 {
140 if (!delegate.containsVertex(vertex))
141 return false;
142 if (remove_subtrees)
143 for(V v : new ArrayList<V>(delegate.getSuccessors(vertex)))
144 removeVertex(v, true);
145 return delegate.removeVertex(vertex);
146 }
147
148
149
150
151
152
153
154
155 public List<V> getPath(V child) {
156 if (!delegate.containsVertex(child))
157 return null;
158 List<V> list = new ArrayList<V>();
159 list.add(child);
160 V parent = getParent(child);
161 while(parent != null) {
162 list.add(list.size(), parent);
163 parent = getParent(parent);
164 }
165 return list;
166 }
167
168 public V getParent(V child) {
169 if (!delegate.containsVertex(child))
170 return null;
171 Collection<V> parents = delegate.getPredecessors(child);
172 if(parents.size() > 0) {
173 return parents.iterator().next();
174 }
175 return null;
176 }
177
178
179
180
181 public V getRoot() {
182 V root = null;
183 for (V v : delegate.getVertices()) {
184 if (delegate.getPredecessorCount(v) == 0) {
185 if (root == null) {
186 root = v;
187 } else {
188
189 return null;
190 }
191 }
192 }
193 return root;
194 }
195
196
197
198
199
200 public void setRoot(V root) {
201 delegate.addVertex(root);
202 }
203
204
205
206
207
208
209
210 public boolean removeChild(V orphan) {
211 return removeVertex(orphan);
212 }
213
214
215
216
217
218
219
220
221 public int getDepth(V v) {
222 return getPath(v).size();
223 }
224
225
226
227
228
229
230 public int getHeight() {
231 int height = 0;
232 for(V v : getVertices()) {
233 height = Math.max(height, getDepth(v));
234 }
235 return height;
236 }
237
238
239
240
241
242
243 public boolean isInternal(V v) {
244 return isLeaf(v) == false && isRoot(v) == false;
245 }
246
247
248
249
250
251 public boolean isLeaf(V v) {
252 return getChildren(v).size() == 0;
253 }
254
255
256
257
258
259 public Collection<V> getChildren(V v) {
260 return delegate.getSuccessors(v);
261 }
262
263
264
265
266
267 public boolean isRoot(V v) {
268 return getParent(v) == null;
269 }
270
271 @Override
272 public int getIncidentCount(E edge)
273 {
274 return 2;
275 }
276
277 @SuppressWarnings("unchecked")
278 @Override
279 public boolean addEdge(E edge, Collection<? extends V> vertices) {
280 Pair<V> pair = null;
281 if(vertices instanceof Pair) {
282 pair = (Pair<V>)vertices;
283 } else {
284 pair = new Pair<V>(vertices);
285 }
286 return addEdge(edge, pair.getFirst(), pair.getSecond());
287 }
288
289
290
291
292 public Collection<V> getRoots() {
293 Collection<V> roots = new HashSet<V>();
294 for(V v : delegate.getVertices()) {
295 if(delegate.getPredecessorCount(v) == 0) {
296 roots.add(v);
297 }
298 }
299 return roots;
300 }
301
302 public Collection<Tree<V, E>> getTrees() {
303 Collection<Tree<V,E>> trees = new HashSet<Tree<V,E>>();
304 for(V v : getRoots()) {
305 Tree<V,E> tree = new DelegateTree<V,E>();
306 tree.addVertex(v);
307 TreeUtils.growSubTree(this, tree, v);
308 trees.add(tree);
309 }
310 return trees;
311 }
312
313
314
315
316
317
318 public void addTree(Tree<V,E> tree) {
319 TreeUtils.addSubTree(this, tree, null, null);
320 }
321
322 public int getChildCount(V vertex)
323 {
324 return delegate.getSuccessorCount(vertex);
325 }
326
327 public Collection<E> getChildEdges(V vertex)
328 {
329 return delegate.getOutEdges(vertex);
330 }
331
332 public E getParentEdge(V vertex)
333 {
334 if (isRoot(vertex))
335 return null;
336 return delegate.getInEdges(vertex).iterator().next();
337 }
338
339 }