-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLinkedBinaryTree.java
More file actions
270 lines (211 loc) · 6.81 KB
/
LinkedBinaryTree.java
File metadata and controls
270 lines (211 loc) · 6.81 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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
package cs2321;
import java.util.Iterator;
import net.datastructures.*;
public class LinkedBinaryTree<E> implements BinaryTree<E>{
protected Node<E> root;
private int size;
//general node creation function
protected Node<E> createNode(E e, Node<E> parent, Node<E> left, Node<E> right){
return new Node<E>(e, parent, left, right);
}
//checks if the node is valid
protected Node<E> validate(Position<E> p) throws IllegalArgumentException{
if(!(p instanceof Node)) {
throw new IllegalArgumentException();
}
Node<E> node = (Node<E>) p;
if(node.getParent() == node) {
throw new IllegalArgumentException();
}
return node;
}
@Override
public Position<E> root() {
return root;
}
public LinkedBinaryTree( ) {
root = null;
size = 0;
}
@Override
public Position<E> parent(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return node.getParent();
}
@Override
public Iterable<Position<E>> children(Position<E> p) throws IllegalArgumentException {
// TODO Auto-generated method stub
return null;
}
@Override
/* count only direct child of the node, not further descendant. */
public int numChildren(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
int num = 0;
if(node.getLeft() != null) { //check if node has left child
num++;
}
if(node.getRight() != null) { //check if node has right child
num++;
}
return num;
}
@Override
public boolean isInternal(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return ((node.getLeft() != null) || (node.getRight() != null)); //if node has a child, it is internal
}
@Override
public boolean isExternal(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return ((node.getLeft() == null) && (node.getRight() == null)); //if node does not have a child, it is external
}
@Override
public boolean isRoot(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return node.getParent() == null; //only root has a null parent
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return root == null; //if there is not a root, there is not a tree
}
@Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return new myIterator();
}
@Override
public Iterable<Position<E>> positions() {
return new PositionIterable();
}
@Override
public Position<E> left(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return node.getLeft();
}
@Override
public Position<E> right(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return node.getRight();
}
@Override
public Position<E> sibling(Position<E> p) throws IllegalArgumentException {
// TODO Auto-generated method stub
return null;
}
/* creates a root for an empty tree, storing e as element, and returns the
* position of that root. An error occurs if tree is not empty.
*/
public Position<E> addRoot(E e) throws IllegalStateException {
if(!isEmpty()) { //if it already has a root, not a legal state
throw new IllegalStateException();
}
root = createNode(e, null, null, null); //make the new root
size = 1; //size is now 1
return root;
}
/* creates a new left child of Position p storing element e, return the left child's position.
* If p has a left child already, throw exception IllegalArgumentExeption.
*/
public Position<E> addLeft(Position<E> p, E e) throws IllegalArgumentException {
Node<E> parent = validate(p); //make sure node is a valid position
if(parent.getLeft() != null) { //if it already has a left node, can't place new node there
throw new IllegalArgumentException();
}
Node<E> child = createNode(e, parent, null, null); //make new node
parent.setLeft(child); //set node as left child of the parent
size++; //increase size of tree
return child;
}
/* creates a new right child of Position p storing element e, return the right child's position.
* If p has a right child already, throw exception IllegalArgumentExeption.
*/
public Position<E> addRight(Position<E> p, E e) throws IllegalArgumentException {
Node<E> parent = validate(p); //make sure node is a valid position
if(parent.getRight() != null) { //if it already has a right node, can't place new node there
throw new IllegalArgumentException();
}
Node<E> child = createNode(e, parent, null, null); //make new node
parent.setRight(child); //set node as right child of the parent
size++; //increase size of the tree
return child;
}
/* Attach trees t1 and t2 as left and right subtrees of external Position.
* if p is not external, throw IllegalArgumentExeption.
*/
public void attach(Position<E> p, LinkedBinaryTree<E> t1, LinkedBinaryTree<E> t2)
throws IllegalArgumentException {
Node<E> node = validate(p);
if(isInternal(p)) { //node must be a leaf node
throw new IllegalArgumentException();
}
size += t1.size() + t2.size(); //add on the size of both trees to the new tree
if(!t1.isEmpty()) { //attach t1 as the left subtree of the node
t1.root.setParent(node);
node.setLeft(t1.root);
t1.root = null;
t1.size = 0;
}
if(!t2.isEmpty()) { //attach t2 as the right subtree of the node
t2.root.setParent(node);
node.setRight(t2.root);
t2.root = null;
t2.size = 0;
}
}
protected static class Node<E> implements Position<E>{
private E element;
private Node<E> parent;
private Node<E> left;
private Node<E> right;
public Node(E e, Node<E> above, Node<E> leftChild, Node<E> rightChild) {
element = e;
parent = above;
left = leftChild;
right = rightChild;
}
@Override
public E getElement() throws IllegalStateException { return element; }
public Node<E> getParent(){ return parent; }
public Node<E> getLeft(){ return left; }
public Node<E> getRight(){ return right; }
public void setParent(Node<E> parentNode){ parent = parentNode; }
public void setLeft(Node<E> leftNode) { left = leftNode; }
public void setRight(Node<E> rightNode) { right = rightNode; }
}
private class PositionIterable implements Iterable<Position<E>>{
@Override
public Iterator<Position<E>> iterator() {
// TODO Auto-generated method stub
return new PositionIterator();
}
}
private class PositionIterator implements Iterator<Position<E>>{
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
@Override
public Position<E> next() {
// TODO Auto-generated method stub
return null;
}
}
private class myIterator implements Iterator<E>{
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
@Override
public E next() {
// TODO Auto-generated method stub
return null;
}
}
}