-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathBinarySearchTreeWithParent.java
169 lines (150 loc) · 4.59 KB
/
BinarySearchTreeWithParent.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
/**
* This class is having two more methods that BinarySearchTree: inorderSuccessor and inorderPredecessor
*/
public class BinarySearchTreeWithParent {
private Node root;
BinarySearchTree() {
}
public Node search(int x) {
return search(this.root, x);
// return searchIteratively(this.root, x);
}
private Node search(Node node, int x) {
if (node == null || node.val == x) return node;
if (node.val > x) {
return search(node.left, x);
} else {
return search(node.right, x);
}
}
private Node searchIteratively(Node node, int x) {
Node res = node;
while (res != null && res.val != x) {
if (res.val > x) {
res = res.left;
} else {
res = res.right;
}
}
return res;
}
public void insert(int x) {
this.root = insert(this.root, x);
// this.root = insertIteratively(this.root, x);
}
public Node insert(Node node, int x) {
if (node == null) return new Node(x);
if (node.val > x) {
node.left = insert(node.left, x);
} else if (node.val < x) {
node.right = insert(node.right, x);
}
return node;
}
public Node insertIteratively(Node node, int x) {
Node newNode = new Node(x);
if (node == null) return newNode;
Node res = node;
while (res != null && res.val != x) {
if (res.val > x) {
if (res.left == null) {
res.left = newNode;
} else {
res = res.left;
}
} else {
if (res.right == null) {
res.right = newNode;
} else {
res = res.right;
}
}
}
return node;
}
/**
* 1) Node to be deleted is leaf: Simply remove from the tree.
*
* 2) Node to be deleted has only one child: Copy the child to the node and
* delete the child
*
* 3) Node to be deleted has two children: Find inorder successor of the node.
* Copy contents of the inorder successor to the node and delete the inorder
* successor. Note that inorder predecessor can also be used.
*
* The important thing to note is, inorder successor is needed only when right
* child is not empty. In this particular case, inorder successor can be
* obtained by finding the minimum value in right child of the node.
*/
public void delete(int x) {
this.root = delete(this.root, x);
}
public Node delete(Node node, int x) {
if (node == null) return null;
if (node.val == x) {
if (node.left == null) {
return node.right;
} else if (node.right == null) {
return node.left;
} else {
Node succ = node.right;
while (succ.left != null) {
succ = succ.left;
}
node.val = succ.val;
node.right = delete(node.right, node.val);
}
} else if (node.val > x) {
node.left = delete(node.left, x);
} else {
node.right = delete(node.right, x);
}
return node;
}
public Node getRoot() {
return this.root;
}
class Node {
int val;
Node left;
Node right;
Node parent;
Node(int x) {
this.val = x;
}
Node(int x, Node p) {
this.val = x;
this.parent = p;
}
public Node inorderSuccessor() {
if (this.right == null) {
Node res = this;
while (res.parent != null && res.parent.right == res) {
res = res.parent;
}
return res.parent;
} else {
Node res = this.right;
while (res.left != null) {
res = res.left;
}
return res;
}
}
public Node inorderPredecessor() {
if (this.left == null) {
Node res = this;
while (res.parent != null && res.parent.left == res) {
res = res.parent;
}
return res.parent;
} else {
Node res = this.left;
while (res.right != null) {
res = res.right;
}
return res;
}
}
}
}