Skip to content

Commit a965fd0

Browse files
committed
add left-leaning red-black tree (llrb.js)
1 parent 05b3da6 commit a965fd0

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

llrb.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
2+
module.exports = llrb;
3+
4+
function llrb(compare) {
5+
return new LLRBTree(compare);
6+
}
7+
8+
function LLRBTree(compare) {
9+
this.compare = compare || defaultCompare;
10+
}
11+
12+
function Node(key, value, red) {
13+
this.key = key;
14+
this.value = value;
15+
this.red = red;
16+
this.left = null;
17+
this.right = null;
18+
}
19+
20+
LLRBTree.prototype = {
21+
find: function (key) {
22+
var x = this.root,
23+
compare = this.compare;
24+
while (x) {
25+
var c = compare(key, x.key);
26+
if (c === 0) return x;
27+
x = c < 0 ? x.left : x.right;
28+
}
29+
return null;
30+
},
31+
32+
insert: function (key, value) {
33+
this.root = insert(this.root, key, value, this.compare);
34+
this.root.red = false;
35+
}
36+
}
37+
38+
function defaultCompare(a, b) {
39+
return a < b ? -1 :
40+
a > b ? 1 : 0;
41+
}
42+
43+
function insert(h, key, value, compare) {
44+
if (!h) return new Node(key, value, true);
45+
46+
var c = compare(key, h.key);
47+
48+
if (c < 0) h.left = insert(h.left, key, value, compare);
49+
else if (c > 0) h.right = insert(h.right, key, value, compare);
50+
else h.value = value;
51+
52+
if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);
53+
if (isRed(h.left) && isRed(h.left.left)) h = rotateRight(h);
54+
if (isRed(h.left) && isRed(h.right)) flipColors(h);
55+
56+
return h;
57+
}
58+
59+
function isRed(h) {
60+
return h && h.red;
61+
}
62+
63+
function rotateRight(h) {
64+
var x = h.left;
65+
h.left = x.right;
66+
x.right = h;
67+
x.red = h.red;
68+
h.red = true;
69+
return x;
70+
}
71+
72+
function rotateLeft(h) {
73+
var x = h.right;
74+
h.right = x.left;
75+
x.left = h;
76+
x.red = h.red;
77+
h.red = true;
78+
return x;
79+
}
80+
81+
function flipColors(h) {
82+
h.red = true;
83+
h.left.red = false;
84+
h.right.red = false;
85+
}

0 commit comments

Comments
 (0)