sonic-forest
Version:
High-performance (binary) tree and sorted map implementation (AVL, Splay, Radix, Red-Black)
149 lines (148 loc) • 3.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteNode = exports.min = exports.deleteMin = exports.balance = exports.moveRedRight = exports.moveRedLeft = exports.rotateRight = exports.rotateLeft = exports.colorFlip = exports.isRed = void 0;
function isRed(node) {
return node ? !node.b : false;
}
exports.isRed = isRed;
function colorFlip(node) {
node.b = !node.b;
if (node.l)
node.l.b = !node.l.b;
if (node.r)
node.r.b = !node.r.b;
}
exports.colorFlip = colorFlip;
function rotateLeft(node) {
const x = node.r;
node.r = x.l;
if (x.l)
x.l.p = node;
x.l = node;
x.p = node.p;
node.p = x;
if (x.p) {
if (x.p.l === node)
x.p.l = x;
else
x.p.r = x;
}
x.b = node.b;
node.b = false;
return x;
}
exports.rotateLeft = rotateLeft;
function rotateRight(node) {
const x = node.l;
node.l = x.r;
if (x.r)
x.r.p = node;
x.r = node;
x.p = node.p;
node.p = x;
if (x.p) {
if (x.p.l === node)
x.p.l = x;
else
x.p.r = x;
}
x.b = node.b;
node.b = false;
return x;
}
exports.rotateRight = rotateRight;
function moveRedLeft(node) {
colorFlip(node);
if (node.r && (node.r.l ? !node.r.l.b : false)) {
node.r = rotateRight(node.r);
node = rotateLeft(node);
colorFlip(node);
}
return node;
}
exports.moveRedLeft = moveRedLeft;
function moveRedRight(node) {
colorFlip(node);
if (node.l && (node.l.l ? !node.l.l.b : false)) {
node = rotateRight(node);
colorFlip(node);
}
return node;
}
exports.moveRedRight = moveRedRight;
function balance(node) {
if (node.r ? !node.r.b : false) {
node = rotateLeft(node);
}
if ((node.l ? !node.l.b : false) && node.l && (node.l.l ? !node.l.l.b : false)) {
node = rotateRight(node);
}
if ((node.l ? !node.l.b : false) && (node.r ? !node.r.b : false)) {
colorFlip(node);
}
return node;
}
exports.balance = balance;
function deleteMin(node) {
if (!node.l) {
return undefined;
}
if (!(node.l ? !node.l.b : false) && node.l && !(node.l.l ? !node.l.l.b : false)) {
node = moveRedLeft(node);
}
node.l = deleteMin(node.l);
if (node.l)
node.l.p = node;
return balance(node);
}
exports.deleteMin = deleteMin;
function min(node) {
while (node.l) {
node = node.l;
}
return node;
}
exports.min = min;
function deleteNode(node, k, comparator) {
if (!node)
return undefined;
const cmp = comparator(k, node.k);
if (cmp < 0) {
if (!node.l)
return node;
if (!(node.l ? !node.l.b : false) && node.l && !(node.l.l ? !node.l.l.b : false)) {
node = moveRedLeft(node);
}
node.l = deleteNode(node.l, k, comparator);
if (node.l)
node.l.p = node;
}
else {
if (node.l ? !node.l.b : false) {
node = rotateRight(node);
}
if (cmp === 0 && !node.r) {
return undefined;
}
if (!node.r)
return node;
if (!(node.r ? !node.r.b : false) && !(node.r.l ? !node.r.l.b : false)) {
node = moveRedRight(node);
}
if (comparator(k, node.k) === 0) {
const minNode = min(node.r);
node.k = minNode.k;
node.v = minNode.v;
node.r = deleteMin(node.r);
if (node.r)
node.r.p = node;
}
else {
node.r = deleteNode(node.r, k, comparator);
if (node.r)
node.r.p = node;
}
}
return balance(node);
}
exports.deleteNode = deleteNode;