-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBinaryTreePreorderTraversal.java
299 lines (262 loc) · 8.46 KB
/
BinaryTreePreorderTraversal.java
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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
package techQuestions;
import java.util.*;
public class BinaryTreePreorderTraversal {
public static void main(String[] args) {
// TODO Auto-generated method stub
// TreeNode root = new TreeNode(3);
// root.left = new TreeNode(9);
// root.right = new TreeNode(20);
// root.right.left = new TreeNode(15);
// root.right.right = new TreeNode(7);
//
// List<List<Integer>> output = levelOrderIterative(root);
//
// System.out.println(output.toString());
int[] test = {8,5,1,7,10};
TreeNode root = bstFromPreorder(test);
List<Integer> output = preorderTraversal(root);
System.out.println(output.toString());
}
// return the root node of a binary search tree that matches the given preorder traversal
// recall that a binary search tree is a binary tree where for every node, any descendant
// of node.left has a value < node.val, and any descendant of node.right has a value of
// > node.val. A preorder traversal displays root first, then traverses left, then
// traverses right
static HashMap<Integer, Integer> indexMap = new HashMap<>();
static int[] preorder = {8,5,1,7,10};
public static TreeNode bstFromPreorder(int[] preorder) {
if (preorder.length == 0) {
TreeNode node = null;
return node;
}
// the root will always be the first element
TreeNode root = new TreeNode(preorder[0]);
// attempt at iterative solution.
Deque<TreeNode> deque = new ArrayDeque<TreeNode>();
// initialize double ended queue with root
deque.push(root);
for (int i = 1; i < preorder.length; i++) {
// look at the last added element of the stack
// and treat it as the parent node
TreeNode peek = deque.peek();
// initialize a child node to be the current element
// we are looking at
TreeNode thisNode = new TreeNode(preorder[i]);
// check if we must adjust the parent that we just peeked
while (!deque.isEmpty() && deque.peek().val < thisNode.val) {
// poping elements off the stack until empty
// or we find a parent > current node
peek = deque.pop();
}
if (peek.val < thisNode.val) {
peek.right = thisNode;
} else {
peek.left = thisNode;
}
// now add the child to the queue and iterate on it
deque.push(thisNode);
}
return root;
// // create sorted copy of preorder
// int[] inorder = Arrays.copyOf(preorder, preorder.length);
// Arrays.sort(inorder); // O(N log N) time to sort array
//
// // now build a hash map where value is the index
// for (int i = 0; i < inorder.length; i++) {
// indexMap.put(inorder[i], i);
// }
//
// return helper(0, inorder.length);
}
static int pre_index = 0;
public static TreeNode helper(int left, int right) {
// base case for recursion as always
if (left == right) {
return null;
}
// root of this tree initialized
int rootValue = preorder[pre_index];
TreeNode root = new TreeNode(rootValue);
// time to split inorder list into left and right subtrees
int index = indexMap.get(rootValue);
System.out.println(index);
// now we do recursive part
pre_index++;
// build left subtree
root.left = helper(left, index);
// build right subtree
root.right = helper(index+1, right);
return root;
}
private static List<Integer> list = new ArrayList<>();
public static List<Integer> preorderTraversal(TreeNode root) {
if (root == null) {
return new ArrayList<Integer>();
}
list.add(root.val);
if (root.left != null) {
preorderTraversal(root.left);
}
if (root.right != null) {
preorderTraversal(root.right);
}
return list;
}
public static List<Integer> preorderTraversalIterative(TreeNode root) {
if (root == null) {
return new ArrayList<Integer>();
}
// the recursive method is trivial. what about iterative?
// we use a stack data structure. pop the current node into the list,
// and then add its two child nodes
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
// stack initialized with the root TreeNode
while (!stack.isEmpty()) {
TreeNode currNode = stack.pop();
list.add(currNode.val);
// add right node to stack first since it will get pushed down
// if there exists a left node
if (currNode.right != null) {
stack.add(currNode.right);
}
// now add left node so that it will be at the top of the stack
if (currNode.left != null) {
stack.add(currNode.left);
}
// stack, if the tree is not only one root node, should have more elements
}
return list;
}
public static List<Integer> inorderTraversal(TreeNode root) {
if (root == null) {
return new ArrayList<Integer>();
}
// keep looking left until there isn't a node there
if (root.left != null) {
inorderTraversal(root.left);
}
// there is no left node, print the root we're currently at
list.add(root.val);
// after left and root has been added to list, then add right
if (root.right != null) {
inorderTraversal(root.right);
}
return list;
}
public static List<Integer> inorderTraversalIterative(TreeNode root) {
if (root == null) {
return new ArrayList<Integer>();
}
// again, the recursive method is trivial. what about iterative?
// we use a stack data structure. pop the current node into the list,
// and then add its root and right nodes
Stack<TreeNode> stack = new Stack<>();
TreeNode leftMost = root;
while (leftMost != null || !stack.isEmpty()) {
while (leftMost != null) {
stack.add(leftMost);
leftMost = leftMost.left;
}
leftMost = stack.pop();
list.add(leftMost.val);
leftMost = leftMost.right;
}
return list;
}
public static List<Integer> postorderTraversal(TreeNode root) {
if (root == null) {
return new ArrayList<Integer>();
}
// keep looking left until there isn't a node there
if (root.left != null) {
inorderTraversal(root.left);
}
// after left has been added to list, then add right
if (root.right != null) {
inorderTraversal(root.right);
}
// there is no left or right node, print the root we're currently at
list.add(root.val);
return list;
}
public static List<Integer> postorderTraversalIterative(TreeNode root) {
if (root == null) {
return new ArrayList<Integer>();
}
// again, the recursive method is trivial. what about iterative?
// we use a stack data structure. pop the current node into the list,
// and then add its root and right nodes
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
while (!stack.isEmpty()) {
TreeNode currNode = stack.pop();
list.add(0, currNode.val);
if (currNode.left != null) {
stack.add(currNode.left);
}
if (currNode.right != null) {
stack.add(currNode.right);
}
}
return list;
}
public static List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<List<Integer>>();
}
levelOrderHelper(root, 0);
return doubleList;
}
private static List<List<Integer>> doubleList = new ArrayList<List<Integer>>();
public static void levelOrderHelper(TreeNode node, int level) {
// using BFS to do level order traversal
int depth = doubleList.size();
if (level == depth) {
doubleList.add(new ArrayList());
}
System.out.println("We are currently at level: " + depth +
" and at node.val of: " + node.val);
// now that a new level has been added, put the node value in that level
doubleList.get(level).add(node.val);
if (node.left != null) {
levelOrderHelper(node.left, level + 1);
}
if (node.right != null) {
levelOrderHelper(node.right, level + 1);
}
}
public static List<List<Integer>> levelOrderIterative(TreeNode root) {
if (root == null) {
return new ArrayList<List<Integer>>();
}
Queue<TreeNode> queue = new LinkedList<>();
// initialize queue with root
queue.add(root);
// while the queue is not empty
int level = 0;
while (!queue.isEmpty()) {
// create new level for output
doubleList.add(new ArrayList());
int queue_size = queue.size();
for (TreeNode element: queue) {
System.out.print(element.val + " ");
}
System.out.println();
System.out.println("The current level is " + queue_size);
for (int i = 0; i < queue_size; i++) {
// first ever node should be root
TreeNode node = queue.poll();
// now add this node value to the output at the current level
doubleList.get(level).add(node.val);
// if there exists a left node:
if (node.left != null) queue.add(node.left);
// if there exists a right node
if (node.right != null) queue.add(node.right);
}
// a new level has been added at the top of the while loop, time to increment
level++;
}
return doubleList;
}
}