UNPKG

sonic-forest

Version:

High-performance (binary) tree and sorted map implementation (AVL, Splay, Radix, Red-Black)

149 lines (148 loc) 3.8 kB
"use strict"; 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;