Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ce10dd9

Browse files
Renamed Tree to RootedTree and added 'contains' and 'find' methods to RootedTree
1 parent 6163af3 commit ce10dd9

File tree

3 files changed

+92
-53
lines changed

3 files changed

+92
-53
lines changed

‎src/com/jwetherell/algorithms/data_structures/Tree.java‎ renamed to ‎src/com/jwetherell/algorithms/data_structures/RootedTree.java‎

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
*
88
* @param <T> type of value stored in nodes.
99
*/
10-
public class Tree<T> {
10+
public class RootedTree<T> {
1111
private T value = null;
1212
private int depth = 0;
13-
private final ArrayList<Tree<T>> ancestors = new ArrayList<>();
13+
private final ArrayList<RootedTree<T>> ancestors = new ArrayList<>();
14+
private final ArrayList<RootedTree<T>> children = new ArrayList<>();
1415

1516
/**
1617
* Exception which can be thrown by lowestCommonAncestor function if two
@@ -29,7 +30,7 @@ public static class NodesNotInSameTreeException extends Exception {}
2930
* @return lower common ancestor
3031
* @throws NodesNotInSameTreeException if nodes don't have common root
3132
*/
32-
public static <S> Tree<S> lowestCommonAncestor(Tree<S> node1, Tree<S> node2) throws NodesNotInSameTreeException {
33+
public static <S> RootedTree<S> lowestCommonAncestor(RootedTree<S> node1, RootedTree<S> node2) throws NodesNotInSameTreeException {
3334
if(node1 == node2) return node1;
3435
else if(node1.depth < node2.depth) return lowestCommonAncestor(node2, node1);
3536
else if(node1.depth > node2.depth) {
@@ -67,7 +68,7 @@ else if(node1.depth > node2.depth) {
6768
* Creates tree with root only.
6869
*
6970
*/
70-
public Tree() {
71+
public RootedTree() {
7172

7273
}
7374

@@ -76,11 +77,12 @@ public Tree() {
7677
*
7778
* @param value value to be stored in root
7879
*/
79-
public Tree(T value) {
80+
public RootedTree(T value) {
8081
this.value = value;
8182
}
8283

83-
private Tree(Tree<T> parent) {
84+
private RootedTree(RootedTree<T> parent) {
85+
parent.children.add(this);
8486
this.ancestors.add(parent);
8587
this.depth = parent.depth + 1;
8688
int dist = 0;
@@ -94,7 +96,7 @@ private Tree(Tree<T> parent) {
9496
}
9597
}
9698

97-
public Tree<T> setValue(T value) {
99+
public RootedTree<T> setValue(T value) {
98100
this.value = value;
99101
return this;
100102
}
@@ -106,8 +108,8 @@ public Tree<T> setValue(T value) {
106108
*
107109
* @return added child
108110
*/
109-
public Tree<T> addChild() {
110-
return new Tree<>(this);
111+
public RootedTree<T> addChild() {
112+
return new RootedTree<>(this);
111113
}
112114

113115
/**
@@ -118,7 +120,7 @@ public Tree<T> addChild() {
118120
* @param value value to be stored in new child
119121
* @return added child
120122
*/
121-
public Tree<T> addChild(T value) {
123+
public RootedTree<T> addChild(T value) {
122124
return addChild().setValue(value);
123125
}
124126

@@ -131,5 +133,35 @@ public T getValue() {
131133
return value;
132134
}
133135

136+
/**
137+
* Finds subtree with given value in the root.
138+
*
139+
* @param value value to be find
140+
* @return subtree with given value in the root
141+
*/
142+
public RootedTree<T> find(T value) {
143+
if(this.value == null) {
144+
if(value == null)
145+
return this;
146+
}
147+
else if(this.value.equals(value))
148+
return this;
149+
for(RootedTree<T> child: children) {
150+
RootedTree<T> res = child.find(value);
151+
if(res != null)
152+
return res;
153+
}
154+
return null;
155+
}
156+
157+
/**
158+
* Returns true if tree contains a node with given value
159+
*
160+
* @param value to be checked
161+
* @return true if tree contains node with given value, false otherwise
162+
*/
163+
public boolean contains(T value) {
164+
return find(value) != null;
165+
}
134166

135167
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.jwetherell.algorithms.data_structures;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.*;
6+
7+
public class RootedTreeTest {
8+
9+
@Test
10+
public void largeTreeTest() throws RootedTree.NodesNotInSameTreeException {
11+
RootedTree<Integer> root = new RootedTree<>();
12+
RootedTree<Integer> left = root.addChild();
13+
RootedTree<Integer> middle = root.addChild();
14+
RootedTree<Integer> right = root.addChild();
15+
16+
//long path
17+
RootedTree<Integer> v = left;
18+
for(int i = 0; i<1000; i++)
19+
v = v.addChild();
20+
RootedTree<Integer> leftRight = left.addChild();
21+
22+
assertEquals(RootedTree.lowestCommonAncestor(v, leftRight), left);
23+
24+
for(int i = 0; i<2000; i++) {
25+
leftRight = leftRight.addChild();
26+
27+
assertEquals(RootedTree.lowestCommonAncestor(v, leftRight), left);
28+
}
29+
30+
assertEquals(RootedTree.lowestCommonAncestor(middle, right), root);
31+
assertEquals(RootedTree.lowestCommonAncestor(root, right), root);
32+
assertEquals(RootedTree.lowestCommonAncestor(root, root), root);
33+
34+
RootedTree<Integer> root2 = new RootedTree<>();
35+
boolean thrownException = false;
36+
try {
37+
RootedTree.lowestCommonAncestor(v, root2);
38+
} catch (RootedTree.NodesNotInSameTreeException e) {
39+
thrownException = true;
40+
}
41+
assertTrue(thrownException);
42+
43+
RootedTree<Integer> deepChild = v.addChild(101);
44+
assertEquals(deepChild, root.find(101));
45+
assertTrue(root.contains(101));
46+
47+
assertNull(root.find(102));
48+
assertFalse(root.contains(102));
49+
}
50+
}

‎test/com/jwetherell/algorithms/data_structures/TreeTest.java‎

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /