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