-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTree.java
More file actions
184 lines (158 loc) · 5.31 KB
/
Tree.java
File metadata and controls
184 lines (158 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import java.util.Iterator;
import java.util.LinkedList;
/*
Authors (group members): Dan Levy, Daniel Griessler, and Frank Savino
Email addresses of group members: dlevy2016@my.fit.edu, dgriessler2016@my.fit.edu, and fsavino2018@my.fit.edu
Group name: Group 2b
Course: CSE 2010
Section: 02
Description of the overall algorithm and key data structures:
* Creates tree structure
* Includes and iterator, adding nodes, and tree traversing
*/
public class Tree<E> {
/*
* Creates an iterator that is filled with nodes from a specific tree traversal method
*/
private class ElementIterator implements Iterator<E> {
Iterator<TreeNode<E>> posIterator = positions().iterator();
// Checks if there is another node
@Override
public boolean hasNext() {
return posIterator.hasNext();
}
// Gets the next node
@Override
public E next() {
return posIterator.next().getElement();
}
// Removes the node
public void remove() {
posIterator.remove();
}
}
// Creates a new instance of ElementIterator
public Iterator<E> iterator() {
return new ElementIterator();
}
// Passes in an empty iterable list to ElementIterator
public Iterable<TreeNode<E>> positions() {
return null;
}
// Creates a new node
protected TreeNode<E> createNode(E element, TreeNode<E> parent, Position position) {
return new TreeNode<E>(element, parent, position);
}
private TreeNode<E> root; // Root node
private int size; // Number of elements in tree
// Gets the root node
public TreeNode<E> getRoot() {
return this.root;
}
// Creates a new instance of the Tree data structure
public Tree(E e, Position position) {
root = new TreeNode<E>(e, null, position);
size ++;
}
public Tree() {
root = null;
}
public TreeNode<E> setRoot(E e, Position position) {
this.root = new TreeNode<E>(e, null, position);
size ++;
return this.root;
}
// Gets number of elements in the tree
public int getSize() {
return this.size;
}
// Checks if the tree is empty
public boolean isEmpty() {
return this.size == 0;
}
// Adds a new node to the tree in correct lexicographical order
public void addChild(TreeNode<E> parentNode, TreeNode<E> childNode) {
if (parentNode.getChildren().size() == 0) { // If tree is empty -> add the node to the beginning of the parentNode's children
parentNode.getChildren().addFirst(childNode);
} else { // Iterate through all children of the parentNode and find the position for the new node in lexicographical order
int counter = 0;
for (TreeNode<E> node: parentNode.getChildren()) {
if (node.compareTo(childNode) < 0) {
counter ++;
} else {
break;
}
}
parentNode.getChildren().add(counter, childNode); // Adds the node to the correct position in the parentNode's children
}
this.size ++; // Increments size of tree
}
// Finds the parentNode of the currentNode in preorder (top-down)
public TreeNode<E> findParent(String parentNode, TreeNode<E> currentNode) {
if (currentNode.getElement().equals(parentNode)) { // If parentNode is the currentNode -> return the currentNode
return currentNode;
} else { // Otherwise recur through the currentNode's children, grandchildren, etc.
for (TreeNode<E> e: currentNode.getChildren()) {
TreeNode<E> current = findParent(parentNode, e);
if (current != null) {
return current;
}
}
return null;
}
}
// Gets all children of the node passed in
public LinkedList<TreeNode<E>> getChildren(TreeNode<E> parentNode) {
return parentNode.getChildren();
}
// Gets parent of node passed in
public TreeNode<E> getParent(TreeNode<E> childNode) {
return childNode.getParent();
}
// Prints tree using indentation for children
public void printPreorderIndent(TreeNode<E> p, int d) {
for (int i = 0; i < d; i ++) { // Adds correct amount of indentation (spaces)
System.out.print(" ");
}
System.out.println(p.getElement());
// Gets all children using recursion
for (TreeNode<E> c: p.getChildren()) {
printPreorderIndent(c, d+1);
}
}
// Traverses tree top-down
private void preorderSubtree(TreeNode<E> rootNode, LinkedList<TreeNode<E>> snapshot) {
snapshot.add(rootNode); // Adds parentNode (rootNode) to snapshot
for (TreeNode<E> node: rootNode.getChildren()) { // Recurs on children
preorderSubtree(node, snapshot);
}
}
// Creates iterator for preorderSubtree
public Iterable<TreeNode<E>> preorder() {
return iterableLinkedList("preorder");
}
// Traverses tree bottom-up
private void postorderSubtree(TreeNode<E> rootNode, LinkedList<TreeNode<E>> snapshot) {
for (TreeNode<E> node: rootNode.getChildren()) {
preorderSubtree(node, snapshot); // Recurs on children
}
snapshot.add(rootNode); // Adds parentNode (rootNode) to snapshot
}
// Creates iterator for postorderSubtre
public Iterable<TreeNode<E>> postorder() {
return iterableLinkedList("postorder");
}
// Calls preorderSubtree or postorderSubtree if the tree is not empty
private Iterable<TreeNode<E>> iterableLinkedList(String order) {
LinkedList<TreeNode<E>> snapshot = new LinkedList<>(); // Creates a snapshot that will contain all of the nodes in the tree
// If the tree is not empty -> call the proper method
if (!this.isEmpty()) {
if (order == "preorder") {
preorderSubtree(this.root, snapshot);
} else {
postorderSubtree(this.root, snapshot);
}
}
return snapshot;
}
}