-
Notifications
You must be signed in to change notification settings - Fork 496
/
BinarySearchTree.java
183 lines (170 loc) · 5.68 KB
/
BinarySearchTree.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
import java.util.NoSuchElementException;
class Node { // Node for Binary Search Tree
public int data;
public Node left;
public Node right;
public Node(int data) { // Initializes node with given data and no chlid
this.data = data;
this.left = null;
this.right = null;
}
}
class BST {
private Node root; // Root of Binary Search Tree
public BST() { // Initializes empty BST
root = null;
}
public BST(int data) { // Initializes root of BST
root = new Node(data);
}
public void insert(int data) {
if (root == null) {
root = new Node(data); // Initialize root with the given data
return;
}
Node newNode = new Node(data); // Create Node for new entry
Node iterator = root; // Temp Node for iterating from root to leaf
Node parent = null; // To store the future parent of new node
while (iterator != null) {
parent = iterator;
if (data <= iterator.data) {
iterator = iterator.left;
}
else {
iterator = iterator.right;
}
}
if (data <= parent.data) {
parent.left = newNode;
}
else {
parent.right = newNode;
}
}
public Node search(int data) { // Returns the Node if element is found else will throw an Exception
Node iterator = root;
while (iterator != null) {
if (iterator.data == data)
return iterator;
else if (data <= iterator.data)
iterator = iterator.left;
else
iterator = iterator.right;
}
throw new NoSuchElementException("Element is not found in BST");
}
public boolean delete(int data) { // Finds the parent of the node to be deleted.
if (root == null) {
throw new NoSuchElementException("Cannot perform delete operation, BST is empty");
}
Node iterator = root;
Node parent = null;
while (iterator != null) {
if (data == iterator.data) {
return deleteNode(data, parent);
} else {
parent = iterator;
if (data <= iterator.data)
iterator = iterator.left;
else
iterator = iterator.right;
}
}
throw new NoSuchElementException("Delete Unsuccessful! Element was not found in BST");
}
private boolean deleteNode(int data, Node parent) {
Node child = null;
boolean position = false; // Indicates position of child wrt to parent, true is left child, false is right child
if (data <= parent.data) {
child = parent.left;
position = true;
}
else
child = parent.right;
if (child.left == child.right) { // Condition for leaf node
child = null;
if (position)
parent.left = null;
else
parent.right = null;
return true;
} else if (child.right == null) { // Condition for non-leaf with no right sub-tree
if (position)
parent.left = child.left;
else
parent.right = child.left;
child.left = null;
child = null;
return true;
} else if (child.left == null) { // Condition for non-leaf with no left sub-tree
if (position)
parent.left = child.right;
else
parent.right = child.right;
child.right = null;
child = null;
return true;
}
else { // Conditon when Node has both subtree avaliable
Node iterator = child.right;
Node parentOfIterator = null;
while(iterator.left != null) { // Finding the leftmost child of right sub-tree
parentOfIterator = iterator;
iterator = iterator.left;
}
child.data = iterator.data;
parentOfIterator.left = null;
iterator = null;
return true;
}
}
public void printInOrder() { // Function to call inorder printing using root
if (root == null)
throw new NoSuchElementException("Cannot print! BST is empty");
print(root);
System.out.println("");
}
private void print(Node iterator) {
if (iterator != null) {
print(iterator.left);
System.out.print(iterator.data + " ");
print(iterator.right);
}
}
}
public class BinarySearchTree {
public static void main(String[] args) {
// Created an empty tree
BST tree = new BST();
// Adding a few test entries
tree.insert(10);
tree.insert(9);
tree.insert(3);
tree.insert(12);
tree.insert(14);
tree.insert(7);
tree.insert(6);
tree.insert(11);
tree.insert(1);
tree.insert(2);
// Test printing
tree.printInOrder();
// Deleting a valid node
tree.delete(9);
// Print again
tree.printInOrder();
// Searching an invalid node, same can be tested for delete as both use same logic
// but with a slight different approach to find the node
try {
tree.search(4);
System.out.println("Node was found successfully.");
} catch (NoSuchElementException e) {
System.out.println("Invalid Search");
}
try {
tree.delete(9);
} catch (NoSuchElementException e) {
System.out.println("Cannot delete, Node not present.");
}
}
}