Skip to content

Commit 8a7c75f

Browse files
committed
Added LR rotations
1 parent 2786d23 commit 8a7c75f

File tree

1 file changed

+100
-42
lines changed

1 file changed

+100
-42
lines changed

SizeBalancedTree/SizeBalancedTree.java

Lines changed: 100 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,44 @@
11
/**
2+
* The Size Balanced Tree (SBT) is a balanced binary search tree that uses the
3+
* size of subtrees to rebalance itself.
4+
*
5+
* See nice article about the SBT:
6+
* http://wcipeg.com/wiki/Size_Balanced_Tree#Insertion
7+
*
8+
* Read the excellent research paper in the research_paper/ folder.
29
*
310
* @author William Fiset, william.alexandre.fiset@gmail.com
411
**/
512

6-
public class SizeBalancedTree <T extends Comparable<T>> {
13+
public class SizeBalancedTree <T extends Comparable<T>> implements Iterable<T> {
714

8-
// Tracks the number of nodes in this BST
15+
private static final int DEFAULT_SIZE = 16;
16+
17+
// Tracks the number of nodes in this tree.
918
private int nodeCount = 0;
1019

11-
// This BST is a rooted tree so we maintain a handle on the root node
20+
// This is a rooted tree so we maintain a handle on the root node.
1221
private Node root = null;
1322

14-
// Internal node containing node references
15-
// and the actual node data
16-
private class Node {
17-
T data;
23+
// Size tracks the number of children nodes below this number.
24+
private int[] sz = new int[DEFAULT_SIZE];
25+
26+
// TODO: Implement TreePrinter interface
27+
class Node {
28+
29+
T value;
30+
31+
int id;
32+
1833
Node left, right;
19-
public Node (Node left, Node right, T elem) {
20-
this.data = elem;
21-
this.left = left;
22-
this.right = right;
34+
35+
public Node (T value) {
36+
this.value = value;
37+
id = nodeCount;
2338
}
2439
}
2540

26-
// Check if this binary tree is empty
41+
// Check if the tree is empty.
2742
public boolean isEmpty() {
2843
return size() == 0;
2944
}
@@ -44,33 +59,72 @@ public boolean add(T elem) {
4459

4560
// Otherwise add this element to the binary tree
4661
} else {
62+
checkSize();
4763
root = add(root, elem);
4864
nodeCount++;
4965
return true;
5066
}
5167

5268
}
5369

70+
private void checkSize() {
71+
if (nodeCount + 1 == sz.length) {
72+
int[] newSz = new int[sz.length * 2];
73+
System.arraycopy(sz, 0, newSz, 0, sz.length);
74+
sz = newSz;
75+
}
76+
}
77+
5478
// Private method to recursively add a value in the binary tree
5579
private Node add(Node node, T elem) {
5680

5781
// Base case: found a leaf node
5882
if (node == null) {
59-
node = new Node (null, null, elem);
60-
83+
node = new Node(elem);
6184
} else {
85+
86+
sz[node.id]++;
87+
6288
// Pick a subtree to insert element
63-
if (elem.compareTo(node.data) < 0) {
89+
if (elem.compareTo(node.value) < 0) {
6490
node.left = add(node.left, elem);
6591
} else {
6692
node.right = add(node.right, elem);
6793
}
6894
}
6995

96+
// Rebalance
7097
return node;
7198

7299
}
73100

101+
private int sz(Node node) {
102+
if (node == null) return 0;
103+
return sz[node.id];
104+
}
105+
106+
private Node rightRotate(Node node) {
107+
Node child = node.left;
108+
node.left = child.right;
109+
child.right = node;
110+
sz[child.id] = sz(node);
111+
sz[node.id] = sz(node.left) + sz(node.right) + 1;
112+
return child;
113+
}
114+
115+
private Node leftRotate(Node node) {
116+
Node child = node.right;
117+
node.right = child.left;
118+
child.left = node;
119+
sz[child.id] = sz(node);
120+
sz[node.id] = sz(child.left) + sz(child.right) + 1;
121+
return child;
122+
}
123+
124+
private Node leftRotate(Node node) {
125+
return null;
126+
}
127+
74128
// Remove a value from this binary tree if it exists, O(n)
75129
public boolean remove(T elem) {
76130

@@ -89,7 +143,7 @@ private Node remove(Node node, T elem) {
89143

90144
if (node == null) return null;
91145

92-
int cmp = elem.compareTo(node.data);
146+
int cmp = elem.compareTo(node.value);
93147

94148
// Dig into left subtree, the value we're looking
95149
// for is smaller than the current value
@@ -111,7 +165,7 @@ private Node remove(Node node, T elem) {
111165

112166
Node rightChild = node.right;
113167

114-
node.data = null;
168+
node.value = null;
115169
node = null;
116170

117171
return rightChild;
@@ -123,7 +177,7 @@ private Node remove(Node node, T elem) {
123177

124178
Node leftChild = node.left;
125179

126-
node.data = null;
180+
node.value = null;
127181
node = null;
128182

129183
return leftChild;
@@ -140,19 +194,19 @@ private Node remove(Node node, T elem) {
140194
Node tmp = findMin(node.right);
141195

142196
// Swap the data
143-
node.data = tmp.data;
197+
node.value = tmp.value;
144198

145199
// Go into the right subtree and remove the leftmost node we
146200
// found and swapped data with. This prevents us from having
147201
// two nodes in our tree with the same value.
148-
node.right = remove(node.right, tmp.data);
202+
node.right = remove(node.right, tmp.value);
149203

150204
// If instead we wanted to find the largest node in the left
151205
// subtree as opposed to smallest node in the right subtree
152206
// here is what we would do:
153207
// Node tmp = findMax(node.left);
154-
// node.data = tmp.data;
155-
// node.left = remove(node.left, tmp.data);
208+
// node.value = tmp.value;
209+
// node.left = remove(node.left, tmp.value);
156210

157211
}
158212

@@ -176,30 +230,34 @@ private Node findMax(Node node) {
176230
return node;
177231
}
178232

179-
// returns true is the element exists in the tree
180-
public boolean contains(T elem) {
181-
return contains(root, elem);
182-
}
183-
184-
// private recursive method to find an element in the tree
185-
private boolean contains(Node node, T elem) {
233+
// Return true/false depending on whether a value exists in the tree.
234+
public boolean contains(T value) {
186235

187-
// Base case: reached bottom, value not found
188-
if (node == null) return false;
236+
Node node = root;
189237

190-
int cmp = elem.compareTo(node.data);
191-
192-
// Dig into the left subtree because the value we're
193-
// looking for is smaller than the current value
194-
if (cmp < 0) return contains(node.left, elem);
238+
if (node == null || value == null) return false;
195239

196-
// Dig into the right subtree because the value we're
197-
// looking for is greater than the current value
198-
else if (cmp > 0) return contains(node.right, elem);
199-
200-
// We found the value we were looking for
201-
else return true;
240+
while(node != null) {
241+
242+
// Compare current value to the value in the node.
243+
int cmp = value.compareTo(node.value);
244+
245+
// Dig into left subtree.
246+
if (cmp < 0) node = node.left;
247+
248+
// Dig into right subtree.
249+
else if (cmp > 0) node = node.right;
250+
251+
// Found value in tree.
252+
else return true;
253+
}
254+
255+
return false;
256+
}
202257

258+
// TODO: Implement iterator. See other BST for examples.
259+
public java.util.Iterator<T> iterator() {
260+
return null;
203261
}
204262

205263
public static void main(String[] args) {

0 commit comments

Comments
 (0)