flo-ll-rb-tree
Version:
A simple left leaning red black tree implementation.
1 lines • 4.59 kB
JavaScript
const t=-1,o=1,r=1,n=0;class e{datum;color=0;parent;extras;"-1";1;constructor(t){this.datum=t}}function u(t){return!!t&&0===t.color}class i{compare;duplicatesAllowed;root;nodeCount;valueCount;constructor(t,o=!0,r){if(this.compare=t,this.duplicatesAllowed=o,this.root=void 0,this.nodeCount=0,this.valueCount=0,r)for(const t of r)this.insert(t)}isEmpty(){return!this.root}find(o){const r=this;let n=this.root;for(;n;){const e=r.compare(o,n.datum);if(0===e)return n;n=n[e>0?1:t]}}toArrayInOrder(){const t=[];return function o(r){r&&(o(r[-1]),t.push(r.datum),void 0!==r.extras&&t.push(...r.extras),o(r[1]))}(this.root),t}insertMulti(t){const o=this;for(const r of t)o.insert(r)}insert(o){const r=this;r.root=function o(n,i){if(void 0===n)return r.valueCount++,r.nodeCount++,new e(i);const a=r.compare(i,n.datum);if(0===a&&(r.duplicatesAllowed?(r.valueCount++,void 0===n.extras?n.extras=[i]:n.extras.push(i)):n.datum=i),0!==a){const r=a>0?1:t;n[r]=o(n[r],i),n[r].parent=n}return u(n[1])&&!u(n[-1])&&(n=s(t,n)),u(n[-1])&&u(n[-1][-1])&&(n=s(1,n)),u(n[-1])&&u(n[1])&&d(n),n}(r.root,o),r.root.color=1,r.root.parent=void 0}remove(t,o=!1,r){const n=this;if(void 0===n.root)return;let e;const i=function t(i,f){const v=n.duplicatesAllowed&&void 0!==i.extras;let m=n.compare(f,i.datum);if(m<0&&!i[-1]||m>0&&!i[1])return i;if(m<0){u(i[-1])||u(i[-1][-1])||(i=l(i));const o=t(i[-1],f);return null===o?null:(i[-1]=o,i[-1]&&(i[-1].parent=i),c(i))}if(u(i[-1])&&(i=s(1,i),m=n.compare(f,i.datum)),0===m&&!i[1]){if(v&&!o){if(void 0===r||!0===r(f,i.datum))return e=i.datum,i.datum=i.extras.pop(),n.valueCount--,0===i.extras.length&&(i.extras=void 0),i;{const t=i.extras;for(let o=0;o<t.length;o++)if(!0===r(f,t[o]))return e=t.splice(o,1)[0],n.valueCount--,0===t.length&&(i.extras=void 0),i;return null}}return void 0===r||!0===r(f,i.datum)?(e=i.datum,n.valueCount-=1+(v?i.extras.length:0),void n.nodeCount--):null}if(u(i[1])||u(i[1][-1])||(i=function(t){return d(t),u(t[-1][-1])&&d(t=s(1,t)),t}(i),m=n.compare(f,i.datum)),0===m)if(v&&!o)if(void 0===r||!0===r(f,i.datum))e=i.datum,i.datum=i.extras.pop(),n.valueCount--,0===i.extras.length&&(i.extras=void 0);else{const t=i.extras;let o=!1;for(let u=0;u<t.length;u++)if(!0===r(f,t[u])){e=t.splice(u,1)[0],n.valueCount--,0===t.length&&(i.extras=void 0),o=!0;break}if(!o)return null}else{if(void 0!==r&&!0!==r(f,i.datum))return null;{n.valueCount-=1+(v?i.extras.length:0),e=i.datum;const t=n.getMinNode(i[1]);i.datum=t?.datum,n.duplicatesAllowed&&(i.extras=t?.extras),i[1]=a(i[1]),n.nodeCount--}}else{const o=t(i[1],f);if(null===o)return null;i[1]=o}return i[1]&&(i[1].parent=i),c(i)}(n.root,t);return null!==i?(n.root=i,void 0!==n.root&&(n.root.color=1,n.root.parent=void 0),e):void 0}findBounds(o){const r=this;let n=r.root;const e=[void 0,void 0];if(void 0===n)return e;for(;n;){const u=r.compare(o,n.datum);u>=0?e[0]=n:e[1]=n,n=n[u>=0?1:t]}return e}findBoundsExcl(o){const r=this,n=r.root,e=[void 0,void 0];return void 0===n||function n(u){for(;u;){const i=r.compare(o,u.datum);if(0===i)return n(u[-1]),void n(u[1]);i>0?e[0]=u:i<0&&(e[1]=u),u=u[i>0?1:t]}}(n),e}findAll(o){const r=this;let n=this.root;for(;n;){const e=r.compare(o,n.datum);if(0===e)return[n.datum,...n.extras?n.extras:[]];n=n[e>0?1:t]}return[]}getMinOrMaxNode(t){return o=>{if(void 0===o&&(o=this.root),o){for(;o[t];)o=o[t];return o}}}getMinNode=this.getMinOrMaxNode(t);getMaxNode=this.getMinOrMaxNode(1);min(t){void 0===t&&(t=this.root);const o=this.getMinNode(t);if(void 0!==o)return o.datum}max(t){void 0===t&&(t=this.root);const o=this.getMaxNode(t);if(void 0!==o)return o.datum}}function s(t,o){const r=o[-t];return o[-t]=r[t],r[t]&&(r[t].parent=o),r[t]=o,o.parent=r,r.color=o.color,o.color=0,r}function a(t){if(t[-1])return u(t[-1])||u(t[-1][-1])||(t=l(t)),t[-1]=a(t[-1]),t[-1]&&(t[-1].parent=t),c(t)}function d(t){t.color=(t.color+1)%2,t[-1].color=(t[-1].color+1)%2,t[1].color=(t[1].color+1)%2}function l(o){if(d(o),u(o[1][-1])){const r=s(1,o[1]);o[1]=r,r.parent=o,d(o=s(t,o))}return o}function c(o){return u(o[1])&&(o=s(t,o)),u(o[-1])&&u(o[-1][-1])&&(o=s(1,o)),u(o[-1])&&u(o[1])&&d(o),o}function f(t){return o=>{let r;return r=void 0!==o.extras?`{${[o.datum,...o.extras].map(t)}}`:t(o.datum),r+(u(o)?"•":"·")}}const v=f(t=>t.toString());function m(t){return o=>{const r=o.root;let n="";return function o(r){void 0!==r&&(n+=t(r),(void 0!==r[-1]||null!=r[1])&&(void 0!==r[-1]&&(n+="(",o(r[-1]),n+=")"),void 0!==r[1]&&(n+="[",o(r[1]),n+="]")))}(r),n}}export{r as BLACK,t as LEFT,i as LlRbTree,e as Node,n as RED,o as RIGHT,u as isRed,f as nodeToStr,v as numberNodeToStr,m as treeToStr};