Skip to content

Commit bdb3dc8

Browse files
committed
Created red-black trees and red-black trees with list
1 parent f863027 commit bdb3dc8

File tree

4 files changed

+890
-0
lines changed

4 files changed

+890
-0
lines changed

RBTree/RBTree.js

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
/**
2+
* The single node of the tree.
3+
* @param key {number} The key of the node.
4+
* @param item {*} The item to store in the node.
5+
* @constructor
6+
*/
7+
function RBNode(key, item) {
8+
/**
9+
* The item stored.
10+
* @type {*}
11+
*/
12+
this.item = item;
13+
/**
14+
* The key of the node.
15+
* @type {number}
16+
*/
17+
this.key = key;
18+
/**
19+
* The parent node. It's null if there's no a parent node.
20+
* @type {RBNode|null}
21+
*/
22+
this.parent = null;
23+
/**
24+
* The left node. It's null if there's no a left node.
25+
* @type {RBNode|null}
26+
*/
27+
this.left = null;
28+
/**
29+
* The right node. It's null if there's no a right node.
30+
* @type {RBNode|null}
31+
*/
32+
this.right = null;
33+
/**
34+
* The type of the node. It's or red or black.
35+
* @type {string}
36+
*/
37+
this.type = 'r';
38+
}
39+
40+
RBTree.prototype = new Aggregate();
41+
RBTree.prototype.constructor = RBTree;
42+
43+
function RBTree() {
44+
/**
45+
* The root of the tree.
46+
* @type {RBNode|null}
47+
*/
48+
this.root = null;
49+
}
50+
51+
/**
52+
* @inheritDoc
53+
*/
54+
RBTree.prototype.getIterator = function () {
55+
return new RBTreeIterator(this);
56+
};
57+
58+
/**
59+
* Insert the item relatives to the key value in the tree.
60+
* @param key {number} The key to store.
61+
* @param item {*} The item to store.
62+
* @return {void}
63+
*/
64+
RBTree.prototype.insert = function (key, item) {
65+
var node = new RBNode(key, item);
66+
if (!this.root) {
67+
this.root = node;
68+
node.type = 'b';
69+
return;
70+
}
71+
var p = this.root;
72+
for (var n = this.root; n;) {
73+
p = n;
74+
if (key < n.key)
75+
n = n.left;
76+
else
77+
n = n.right;
78+
}
79+
node.parent = p;
80+
if (!p)
81+
this.root = node;
82+
else if (key < p.key)
83+
p.left = node;
84+
else
85+
p.right = node;
86+
87+
this.insertFixUp(node);
88+
};
89+
90+
/**
91+
* Preserve the properties of the tree after an insert.
92+
* @param node {RBNode} The node to insert.
93+
* @return {void}
94+
*/
95+
RBTree.prototype.insertFixUp = function (node) {
96+
for (var parent = node.parent; parent && parent.type === 'r'; parent = node.parent) {
97+
if (parent === parent.parent.left) {
98+
var uncle = parent.parent.right;
99+
if (uncle && uncle.type === 'r') {
100+
parent.type = 'b';
101+
uncle.type = 'b';
102+
parent.parent.type = 'r';
103+
node = parent.parent;
104+
} else if (node === parent.right) {
105+
node = parent;
106+
this.leftRotate(node);
107+
} else {
108+
parent.type = 'b';
109+
parent.parent.type = 'r';
110+
this.rightRotate(parent.parent);
111+
}
112+
} else {
113+
var uncle = parent.parent.left;
114+
if (uncle && uncle.type === 'r') {
115+
parent.type = 'b';
116+
uncle.type = 'b';
117+
parent.parent.type = 'r';
118+
node = parent.parent;
119+
} else if (node === parent.left) {
120+
node = parent;
121+
this.rightRotate(node);
122+
} else {
123+
parent.type = 'b';
124+
parent.parent.type = 'r';
125+
this.leftRotate(parent.parent);
126+
}
127+
}
128+
}
129+
this.root.type = 'b';
130+
};
131+
132+
/**
133+
* Delete the node from the tree.
134+
* @param node {RBNode} The node to delete.
135+
* @return {void}
136+
*/
137+
RBTree.prototype.deleteNode = function (node) {
138+
var successor;
139+
if (!node.left || !node.right)
140+
successor = node;
141+
else {
142+
successor = this.successor(node);
143+
node.key = successor.key;
144+
node.item = successor.item;
145+
}
146+
var child;
147+
if (!successor.left)
148+
child = successor.right;
149+
else
150+
child = successor.left;
151+
if (child)
152+
child.parent = successor.parent;
153+
if (!successor.parent)
154+
this.root = child;
155+
else if (successor === successor.parent.left)
156+
successor.parent.left = child;
157+
else
158+
successor.parent.right = child;
159+
160+
if (successor.type === 'b')
161+
this.deleteFixUp(child, successor.parent);
162+
};
163+
164+
/**
165+
* Preserve the properties of the tree after a deletion.
166+
* @param node {RBNode} The node to delete.
167+
* @param parent {RBNode} The parent of the node.
168+
* @return {void}
169+
*/
170+
RBTree.prototype.deleteFixUp = function (node, parent) {
171+
while (node !== this.root && (!node || node.type === 'b')) {
172+
if (node === parent.left) {
173+
var brother = parent.right;
174+
if (brother && brother.type === 'r') {
175+
brother.type = 'b';
176+
parent.type = 'r';
177+
this.leftRotate(parent);
178+
brother = parent.right;
179+
}
180+
if (brother && (!brother.left || brother.left.type === 'b') && (!brother.right || brother.right.type === 'b')) {
181+
brother.type = 'r';
182+
node = parent;
183+
} else {
184+
if (!brother.right || brother.right.type === 'b') {
185+
brother.left.type = 'b';
186+
brother.type = 'r';
187+
this.rightRotate(brother);
188+
brother = parent.right;
189+
}
190+
brother.type = parent.type;
191+
parent.type = 'b';
192+
brother.right.type = 'b';
193+
this.leftRotate(parent);
194+
node = this.root;
195+
}
196+
} else {
197+
var brother = parent.left;
198+
if (brother && brother.type === 'r') {
199+
brother.type = 'b';
200+
parent.type = 'r';
201+
this.rightRotate(parent);
202+
brother = parent.left;
203+
}
204+
if (brother && (!brother.left || brother.left.type === 'b') && (!brother.right || brother.right.type === 'b')) {
205+
brother.type = 'r';
206+
node = parent;
207+
} else {
208+
if (!brother.left || brother.left.type === 'b') {
209+
brother.right.type = 'b';
210+
brother.type = 'r';
211+
this.leftRotate(brother);
212+
brother = parent.left;
213+
}
214+
brother.type = parent.type;
215+
parent.type = 'b';
216+
brother.left.type = 'b';
217+
this.rightRotate(parent);
218+
node = this.root;
219+
}
220+
}
221+
parent = node.parent;
222+
}
223+
if (node)
224+
node.type = 'b';
225+
};
226+
227+
/**
228+
* Get the node with the key next to the param node key.
229+
* @param node {RBNode} The node of which search the successor.
230+
* @return {RBNode} The node found.
231+
*/
232+
RBTree.prototype.successor = function (node) {
233+
if (node.right)
234+
return this.minimum(node.right);
235+
var parent = node.parent;
236+
while (parent && node === parent.right) {
237+
node = parent;
238+
parent = parent.parent;
239+
}
240+
return parent;
241+
};
242+
243+
/**
244+
* Get the node with the key previous to the param node key.
245+
* @param node {RBNode} The node of which search the predecessor.
246+
* @return {RBNode} The node found.
247+
*/
248+
RBTree.prototype.predecessor = function (node) {
249+
if (node.left)
250+
return this.maximum(node.left);
251+
var parent = node.parent;
252+
while (parent && node === parent.left) {
253+
node = parent;
254+
parent = parent.parent;
255+
}
256+
return parent;
257+
};
258+
259+
/**
260+
* Search the item relatives to the key.
261+
* @param key {Number} The key to find.
262+
* @param [node = root] {RBNode} The node from which start the search.
263+
* @return {*} The item found or undefined if there isn't the key in the tree.
264+
*/
265+
RBTree.prototype.search = function (key, node) {
266+
node = node || this.root;
267+
while (node && key !== node.key)
268+
if (key < node.key)
269+
node = node.left;
270+
else
271+
node = node.right;
272+
if (node)
273+
return node.item;
274+
return undefined;
275+
};
276+
277+
/**
278+
* Get the item relatives to the minimum key stored in the tree.
279+
* @param [node = root] {Node} The node from which start the search.
280+
* @return {RBNode} The node found.
281+
*/
282+
RBTree.prototype.minimum = function (node) {
283+
node = node || this.root;
284+
while (node && node.left)
285+
node = node.left;
286+
return node;
287+
};
288+
289+
/**
290+
* Get the item relatives to the maximum key stored in the tree.
291+
* @param [node = root] {Node} The node from which start the search.
292+
* @return {RBNode} The node found.
293+
*/
294+
RBTree.prototype.maximum = function (node) {
295+
node = node || this.root;
296+
while (node && node.right)
297+
node = node.right;
298+
return node;
299+
};
300+
301+
/**
302+
* Rotate the node with its right child.
303+
* @param node {RBNode} The node to rotate.
304+
* @return {void}
305+
*/
306+
RBTree.prototype.leftRotate = function (node) {
307+
var child = node.right;
308+
node.right = child.left;
309+
if (child.left !== null)
310+
child.left.parent = node;
311+
child.parent = node.parent;
312+
if (node.parent === null)
313+
this.root = child;
314+
else if (node === node.parent.left)
315+
node.parent.left = child;
316+
else
317+
node.parent.right = child;
318+
node.parent = child;
319+
child.left = node;
320+
};
321+
322+
/**
323+
* Rotate the node with its left child.
324+
* @param node {RBNode} The node to rotate.
325+
* @return {void}
326+
*/
327+
RBTree.prototype.rightRotate = function (node) {
328+
var child = node.left;
329+
node.left = child.right;
330+
if (child.right !== null)
331+
child.right.parent = node;
332+
child.parent = node.parent;
333+
if (node.parent === null)
334+
this.root = child;
335+
else if (node === node.parent.left)
336+
node.parent.left = child;
337+
else
338+
node.parent.right = child;
339+
node.parent = child;
340+
child.right = node;
341+
};

0 commit comments

Comments
 (0)