@dsinjs/binary-tree
Version:
Binary Trees for your DS in JS
934 lines (930 loc) • 34.2 kB
JavaScript
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BTree = void 0;
var btreenode_1 = require("./btreenode");
var UnreachableError = /** @class */ (function (_super) {
__extends(UnreachableError, _super);
function UnreachableError(msg) {
var _this = _super.call(this, msg) || this;
_this.name = "UnreachableError";
return _this;
}
return UnreachableError;
}(Error));
var FilteredRootError = /** @class */ (function (_super) {
__extends(FilteredRootError, _super);
function FilteredRootError(msg) {
var _this = _super.call(this, msg) || this;
_this.name = "FilteredRootError";
return _this;
}
return FilteredRootError;
}(Error));
// if Symbol is not available in window
if (typeof window !== "undefined") {
if (typeof Symbol === "undefined") {
var win = window;
win.Symbol = {};
win.Symbol.iterator = "==iterator==";
}
}
/**
* BTree main class
* @class
* @public
* @example
* new BTree(10);
* new BTree({ root: 10 });
* new BTree({ value: 10 });
*/
var BTree = /** @class */ (function () {
/**
* Constructor for Binary Tree.
* @param {BTreeRootAttrStruct|BTreeValueAttrStruct|T} attr Can be of type object, string, number. In case of object root/value property is expected to be value of root node.
* @constructor
*/
function BTree(attr) {
/**
* Depth of the binary tree.
* @type {number}
* @property depth
*/
this.depth = 1;
if (typeof attr == "object" && typeof attr.root !== "undefined") {
this.root = new btreenode_1.BTreeNode({ value: attr.root });
}
else if (typeof attr == "object" && typeof attr.value !== "undefined") {
this.root = new btreenode_1.BTreeNode({ value: attr.value });
}
else {
this.root = new btreenode_1.BTreeNode({ value: attr });
}
this.depth = this.root.getDepth();
}
/**
* Returns string value of given tree.
* @method toString
* @member
* @public
* @example
* var tree = new BTree(10);
* tree.insert(10);
* tree.insert(20);
* tree.insert(30);
* tree.toString(); // "10102030"
*/
BTree.prototype.toString = function () {
return this.root.toString();
};
/**
* Returns JSON Form.
* @method toJSON
* @member
* @public
* @returns {BTreeNodeStruct} Returns json form of a given tree.
* @example
* var tree = new BTree(10);
* tree.insert(20);
* tree.toJSON(); // {value:10,lNode:{value:20,lNode:null,rNode:null},rNode:null}
*/
BTree.prototype.toJSON = function () {
return this.root.toJSON();
};
/**
* Returns array value.
* @method toArray
* @member
* @public
* @returns {Array<BTreeNode>} Returns array form of given tree.
* @example
* var tree = new BTree(10);
* tree.insert(20);
* tree.toArray(); // => [{value:10,...},{value:20,...}]
*/
BTree.prototype.toArray = function () {
var arr = [];
this.each(function (node, index) {
arr.push(node);
});
return arr;
};
/**
* Returns array of values of the tree.
* @method toFlatArray
* @member
* @public
* @returns {Array<T>} Returns array form of given tree.
* @example
* var tree = new BTree(10);
* tree.insert(20);
* tree.toFlatArray(); // => [10,20]
*/
BTree.prototype.toFlatArray = function () {
var arr = [];
this.each(function (node, index) {
arr.push(node.value);
});
return arr;
};
/**
* Inserts the given value to the tree where first free left child node is found.
* @param {any} val any type of value to be added to tree node.
* @returns {BTreeNode} Returns newly created BTreeNode.
* @method insert
* @member
* @example
* var tree = new BTree(10);
* tree.insert(10);
* tree.insert(20);
* tree.insert(30);
* tree.toString(); // "10102030"
*/
BTree.prototype.insert = function (val) {
return this.insertLeftMost(val);
};
/**
* Inserts the given value to the tree where first free left child node is found.
* @param {T} val any type of value to be added to tree node.
* @method insertLeftMost
* @member
* @returns {BTreeNode<T>} Returns newly created BTreeNode.
*/
BTree.prototype.insertLeftMost = function (val) {
var node = this.root;
while (node.lNode != null) {
node = node.lNode;
}
node.lNode = new btreenode_1.BTreeNode({ value: val });
this.depth = this.root.getDepth();
return node.lNode;
};
/**
* Inserts the given value to the tree where first free right child node is found.
* @param {T} val any type of value to be added to tree node.
* @method insertRightMost
* @member
* @public
* @returns {BTreeNode<T>} Returns newly created BTreeNode.
*/
BTree.prototype.insertRightMost = function (val) {
var node = this.root;
while (node.rNode != null) {
node = node.rNode;
}
node.rNode = new btreenode_1.BTreeNode({ value: val });
this.depth = this.root.getDepth();
return node.rNode;
};
/**
* Deletes given value from tree.
* Travarsal = Root -> L -> R.
* @param {T} val Value to be removed.
* @returns {BTreeNode<T>} Returns removed BTreeNode.
* @method delete
* @member
* @public
*/
BTree.prototype.delete = function (val) {
/**
* @private
* @param {BTreeNode<T>} currNode Current node.
* @returns {BTreeNode<T>} Returns removed BTreeNode.
*/
var recDel = function (currNode) {
if (currNode == null) {
return currNode;
}
var cacheRetLeft = currNode.lNode;
var cacheRetRight = currNode.rNode;
if (cacheRetLeft == null && cacheRetRight == null) {
return null;
}
if (currNode.lNode && currNode.lNode.value === val) {
currNode.lNode = null;
return cacheRetLeft;
}
if (currNode.rNode && currNode.rNode.value === val) {
currNode.rNode = null;
return cacheRetRight;
}
var delL = recDel(currNode.lNode);
var delR = (!delL) ? recDel(currNode.rNode) : null;
return delL || delR;
};
var delItem = recDel(this.root);
this.depth = this.root.getDepth();
return delItem;
};
/**
* Inserts given element at given location. If location is already taken then it does not insert any value.
* @param {T} val value to insert.
* @param {number} index index at which to append new element to.
* @method insertAt
* @member
* @public
* @throws UnreachableError
* @example
* tree.insertAt(20,2);
*/
BTree.prototype.insertAt = function (val, index) {
var e_1, _a;
var path = BTree.getPathFromIndex(index);
var currNode = this.root;
try {
for (var _b = __values(path.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = __read(_c.value, 2), index_1 = _d[0], item = _d[1];
if (item === 'L') {
if (currNode.lNode == null && path.length !== index_1 + 1) {
throw new UnreachableError('Given index cannot be reached');
}
else if (currNode.lNode == null) {
currNode.lNode = new btreenode_1.BTreeNode({ value: val });
}
else {
currNode = currNode.lNode;
}
}
if (item === 'R') {
if (currNode.rNode == null && path.length !== index_1 + 1) {
throw new UnreachableError('Given index cannot be reached');
}
else if (currNode.rNode == null) {
currNode.rNode = new btreenode_1.BTreeNode({ value: val });
}
else {
currNode = currNode.rNode;
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
this.depth = this.root.getDepth();
};
/**
* Breadth first search. Executes given callback functions with parameters BTreeNode and path index for each node in BFS fashion.
* @param {{(node: BTreeNode<T>, index: number) => any}} callback A callback function for execution of each node.
* @method traverseBFS
* @member
* @public
* @returns {void} no value.
*/
BTree.prototype.traverseBFS = function (callback) {
var currCount = 0;
var children = [];
/**
*
* @param {BTreeNode<T>} currNode current node in recursion.
* @private
*/
var recInser = function (currNode, currPath) {
if (currNode != null) {
var currPathL = JSON.parse(JSON.stringify(currPath));
currPathL.push('L');
var currPathR = JSON.parse(JSON.stringify(currPath));
currPathR.push('R');
children.push({ node: currNode.lNode, path: currPathL });
children.push({ node: currNode.rNode, path: currPathR });
callback(currNode, BTree.getIndexFromPath(currPath));
}
currCount++;
if (children.length) {
var item = children.splice(0, 1)[0];
return recInser(item.node, item.path);
}
else {
return;
}
};
recInser(this.root, ['U']);
};
/**
* Depth first search, Executes given callback functions with parameters BTreeNode and path index for each node in DFS fashion.
* @param {{(node: BTreeNode<T>, index: number) => any}} callback A callback function for execution of each node.
* @method traverseDFS
* @member
* @public
* @returns {void} no value.
*/
BTree.prototype.traverseDFS = function (callback) {
/**
*
* @param {BTreeNode<T>} currNode Currently processing node.
* @param {Array<'U'|'L'|'R'>} path current path
* @private
*/
var recFnc = function (currNode, path) {
if (currNode !== null) {
callback(currNode, BTree.getIndexFromPath(path));
if (currNode.lNode !== null) {
var lPath = JSON.parse(JSON.stringify(path));
lPath.push('L');
recFnc(currNode.lNode, lPath);
}
if (currNode.rNode !== null) {
var rPath = JSON.parse(JSON.stringify(path));
rPath.push('R');
recFnc(currNode.rNode, rPath);
}
}
};
recFnc(this.root, ['U']);
};
/**
* Breadth first search. Executes given callback functions with parameters BTreeNode and path index for each node in BFS fashion.
* @param {{(node: BTreeNode<T>, index: number) => any}} callback A callback function for execution of each node.
* @method each
* @member
* @public
* @returns {void} no value.
*/
BTree.prototype.each = function (callback) {
return this.traverseBFS(callback);
};
/**
* Breadth first search. Executes given callback functions with parameters BTreeNode and path index for each node in BFS fashion.
* @param {{(node: BTreeNode<T>, index: number) => any}} callback A callback function for execution of each node.
* @method forEach
* @member
* @public
* @returns {void} no value.
*/
BTree.prototype.forEach = function (callback) {
return this.traverseBFS(callback);
};
/**
* Returns an iterable of key, value pairs for every entry in the tree.
* @method [Symbol.iterator]
* @member
* @public
* @example
* var tree = new BTree(10);
* for (const node of tree) {
* console.log(node.value); // 10
* }
*/
BTree.prototype[Symbol.iterator] = function () {
var curr = -1;
var arr = this.toArray();
return {
/**
* @returns { {value: BTreeNode<T>, done: boolean} }
* @private
*/
next: function () {
curr++;
return {
value: (arr[curr] === void 0) ? void 0 : arr[curr],
done: !!(curr === arr.length)
};
}
};
};
/**
* Returns an iterable of key, value pairs for every entry in the tree.
* @method entries
* @member
* @public
* @returns {IterableIterator<[number, BTreeNode<T>]>} Iterable for iterations.
* @example
* var tree = new BTree(10);
* for (const [index, node] of tree.entries()) {
* console.log(index, node.value); // 0, 10
* }
*/
BTree.prototype.entries = function () {
return this.toArray().entries();
};
/**
* Maps current tree values to a new tree with modifying the values using given callback function.
* Uses BFS.
* @param {{(value: T) => T}} callback callback function for value modifier.
* @method map
* @member
* @public
* @returns {BTree<T>} A new BTree
* @example
* var tree = BTree.fromArray([10, 20, 30, 40]);
* var tree2 = tree.map(n => n * 2);
* var arr2 = tree2.toArray(); // [{value:20,...},{value:40,...},{value:60,...},{value:80,...}]
*/
BTree.prototype.map = function (callback) {
var newTree = new BTree(callback(this.root.value));
this.each(function (node, index) {
if (index !== 1) {
var retVal = callback(node.value);
newTree.insertAt(retVal, index);
}
});
return newTree;
};
/**
* Filters each item based on given filter function
* @param {{(value: T) => boolean}} filterFnc callback function for filtering purpose.
* @method filter
* @member
* @public
* @throws FilteredRootError, Error when root node gets filtered out.
* @returns {BTree<T>} New filtered instance of tree.
* @example
* var tree = BTree.fromArray([10, 20, 30, 40]);
* var tree2 = tree.filter(n => !!(n % 4 === 0 || n === 10));
* var arr2 = tree2.toArray(); // [{value:10,...},{value:20,...},{value:40,...}]
*/
BTree.prototype.filter = function (filterFnc) {
if (!filterFnc(this.root.value)) {
throw new FilteredRootError("Root node cannot be filtered. If you want to filter out root node, you can use emptry BTree instance.");
}
var newTree = new BTree(this.root.value);
this.each(function (node, index) {
if (index !== 1) {
var canBeInserted = filterFnc(node.value);
if (canBeInserted) {
newTree.insertAt(node.value, index);
}
}
});
return newTree;
};
/**
* Reduces each node values using reduceFunction and returns final value.
* @param {(next: T2, value: T, index: number, tree: BTree<T>) => T2} reduceFunction callback function for reducing each node value to a final value.
* @param {T2} initialValue Optional, Accumulator/Initial value.
* @method reduce<T2>
* @member
* @public
* @returns {T2} Returns reduceed value
* @example
* var tree = BTree.fromArray([10, 20, 30, 40]);
* var sum = tree.reduce((acc, node) => acc + node); // => 100
*/
BTree.prototype.reduce = function (reduceFunction, initialValue) {
var _this = this;
if (initialValue === void 0) { initialValue = 0; }
var next = initialValue;
this.each(function (node, index) {
next = reduceFunction(next, node.value, index, _this);
});
return next;
};
/**
* Reverses the current Binary Tree, Left Node becomes Right node and vise versa.
* Does not return new instance, returns current tree instance.
* @method reverse
* @member
* @public
* @returns {BTree<T>} Returns current tree instance.
* @example
* var tree = BTree.fromArray([10, 20, 30, 40, 50, 60, 70, 80]);
* tree.reverse().toArray(); // => [10, 30, 20, 70, 60, 50, 40, 80]
*/
BTree.prototype.reverse = function () {
var trav = function (currNode) {
if (currNode === null) {
return;
}
var temp = currNode.lNode;
currNode.lNode = currNode.rNode;
currNode.rNode = temp;
trav(currNode.lNode);
trav(currNode.rNode);
};
trav(this.root);
return this;
};
/**
* Returns first index of a value matched, if it is not present, it returns -1.
* @param {T} value Any value to find.
* @method indexOf
* @member
* @public
* @returns {number} Returns index of given item.
* @example
* var tree = BTree.fromArray([10, 20, 30, 40, 50, 60, 70, 80]);
* tree.indexOf(30); // => 3
* tree.indexOf(51); // => -1
*/
BTree.prototype.indexOf = function (value) {
var retIndex = -1;
this.each(function (node, index) {
if (node.value === value && retIndex === -1) {
retIndex = index;
}
});
return retIndex;
};
/**
* Checks if given item exists or not, returns boolean.
* @param {T} value Any value to check if it exists or not.
* @method includes
* @member
* @public
* @returns {boolean} Returns true if it is present, otherwise false.
* @example
* var tree = BTree.fromArray([10, 20, 30, 40, 50, 60, 70, 80]);
* tree.includes(30); // true
* tree.includes(51); // false
*/
BTree.prototype.includes = function (value) {
return this.indexOf(value) !== -1;
};
/**
* Checks if given item exists or not, returns boolean.
* @param {T} value Any value to check if it exists or not.
* @method exists
* @member
* @public
* @returns {boolean} Returns true if it is present, otherwise false.
* @example
* var tree = BTree.fromArray([10, 20, 30, 40, 50, 60, 70, 80]);
* tree.exists(30); // true
* tree.exists(51); // false
*/
BTree.prototype.exists = function (value) {
return this.indexOf(value) !== -1;
};
/**
* Checks if given item exists or not, returns boolean.
* @param {T} value Any value to check if it exists or not.
* @method has
* @member
* @public
* @returns {boolean} Returns true if it is present, otherwise false.
* @example
* var tree = BTree.fromArray([10, 20, 30, 40, 50, 60, 70, 80]);
* tree.has(30); // true
* tree.has(51); // false
*/
BTree.prototype.has = function (value) {
return this.indexOf(value) !== -1;
};
/**
* Sorts the tree based on compare function, Has option to sort only at children level.
* @param {Function} compareFnc Function used to determine the order of the elements. It is expected to return
* a negative value if first argument is less than second argument, zero if they're equal and a positive
* value otherwise. If omitted, the elements are sorted in ascending, ASCII character order.
* ```ts
* (a, b) => a - b)
* ```
* @param {boolean} atOnlyFirstChildLevel Optiona, Flag to specify if first child of each node should sorted. Default is `false`.
* @method sort
* @member
* @public
* @returns {void} Returns undefined.
* @example
* var tree = BTree.fromArray([10, 200, 100, 50, 60, 90, 5, 3]);
* tree.sort().toFlatArray(); // => [3,5,10,50,60,90,100,200]
*/
BTree.prototype.sort = function (compareFnc, atOnlyFirstChildLevel) {
if (compareFnc === void 0) { compareFnc = function (a, b) {
if (a === void 0) { a = 0; }
if (b === void 0) { b = 0; }
return (a < b) ? -1 : (a == b) ? 0 : 1;
}; }
if (atOnlyFirstChildLevel === void 0) { atOnlyFirstChildLevel = false; }
if (atOnlyFirstChildLevel) {
var DFS_1 = function (node) {
if (node !== null) {
var out = compareFnc(node.lNode, node.rNode);
if (out > 0) {
var temp = node.lNode;
node.lNode = node.rNode;
node.rNode = temp;
}
DFS_1(node.lNode);
DFS_1(node.rNode);
}
};
DFS_1(this.root);
}
else {
var arr_1 = [];
var arrBFS_1 = [];
var counter = 0;
var children_1 = [];
var BFS_1 = function (node) {
if (node !== null && node.lNode !== null) {
children_1.push(node.lNode);
}
if (node !== null && node.rNode !== null) {
children_1.push(node.rNode);
}
if (node !== null) {
arrBFS_1.push(node);
arr_1.push(node.value);
}
if (children_1.length !== 0) {
var first = children_1[0];
children_1.splice(0, 1);
BFS_1(first);
}
};
BFS_1(this.root);
while (arr_1.length !== 0) {
var min = arr_1[0];
var minIndex = 0;
for (var i = 1; i < arr_1.length; i++) {
var out = compareFnc(min, arr_1[i]);
if (out > 0) {
min = arr_1[i];
minIndex = i;
}
}
arrBFS_1[counter].value = min;
arr_1.splice(minIndex, 1);
counter++;
}
}
};
/**
* Prints entire tree on the console, useful for logging and checking status.
* @method print
* @member
* @public
* @returns {void} Returns undefined.
* @example
* var tree = BTree.fromArray([1, 2, 3]);
* tree.print();
* 1 (1)
* |- 2 (2)
* |- 3 (3)
*/
BTree.prototype.print = function () {
var isit = false;
this.traverseDFS(function (node, index) {
var len = BTree.getPathFromIndex(index).length;
var isFirst = (isit) ? " |-".repeat(len - 1) : "";
console.log(isFirst, node.value, "(" + index + ")");
isit = true;
});
};
/**
* Returns the first matched tree node. Traverses using BFS.
* @param {T} item any value to find inside the tree.
* @method find
* @member
* @public
* @returns {BTreeNode<T> | null} Returns the first matched tree node, if not found, returns null.
* @example
*/
BTree.prototype.find = function (item) {
var retNode = null;
this.each(function (node, index) {
if (node.value === item && retNode === null) {
retNode = node;
}
});
return retNode;
};
/**
* Returns index value from given path.
* @param {Array<'U'|'L'|'R'>} path Array for U L or R, which represents the quickest path to get to a node.
* @returns {number} Returns index value.
* @method getIndexFromPath
* @public
* @static
* @member
*/
BTree.getIndexFromPath = function (path) {
path = JSON.parse(JSON.stringify(path));
var score = 1;
while (path.length != 0) {
if (path[0] === 'U') {
path.splice(0, 1);
}
else if (path[0] === 'L') {
score = score * 2;
path.splice(0, 1);
}
else if (path[0] === 'R') {
score = score * 2 + 1;
path.splice(0, 1);
}
}
return score;
};
/**
* Returns Path equivalent to the given index.
* @param {number} index Index number from which path to be calculated.
* @returns {Array<'U'|'L'|'R'>} Path equivalent to the given index.
* @method getPathFromIndex
* @public
* @static
*/
BTree.getPathFromIndex = function (index) {
var path = [];
while (index != 1) {
if (index % 2 === 0) {
path.push('L');
}
else {
path.push('R');
index = index - 1;
}
index = index / 2;
}
path.push('U');
path = path.reverse();
return path;
};
/**
* Converts given values into a Binary Tree.
* @param {T2[]} arr Any array of values.
* @returns {BTree<T2>} Newly generated tree.
* @method fromArray
* @static
* @public
* @example
* var tree = BTree.fromArray([10,20,30,40]);
*/
BTree.fromArray = function (arr) {
var e_2, _a;
var newArr = JSON.parse(JSON.stringify(arr));
var tree = new BTree(newArr[0]);
try {
for (var _b = __values(arr.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = __read(_c.value, 2), index = _d[0], item = _d[1];
if (index !== 0) {
tree.insertAt(item, index + 1);
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
return tree;
};
return BTree;
}());
exports.BTree = BTree;
if (typeof module != "undefined") {
module.exports = { BTree: BTree, BTreeNode: btreenode_1.BTreeNode };
}
if (typeof window != "undefined") {
window.DSinJS = window.DSinJS || {};
window.DSinJS.BTree = BTree;
}
},{"./btreenode":2}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BTreeNode = void 0;
/**
* Binary Tree node class, contains 2 child nodes and single value.
* @class BTreeNode
* @public
* @example
* var node = new BTreeNode({ value: 15 });
* var node3 = new BTreeNode({ value: 30 });
* var node2 = new BTreeNode({ value: 20, rNode: node, lNode: node3 });
* console.log(node2.lNode.value); // 30
*/
var BTreeNode = /** @class */ (function () {
/**
*
* @param {BTreeNodeStruct} attr attributes to initialize the node.
*/
function BTreeNode(attr) {
this.value = attr.value || null;
this.lNode = attr.lNode || null;
if (!this.lNode instanceof BTreeNode) {
this.lNode = new BTreeNode(this.lNode);
}
this.rNode = attr.rNode || null;
if (!this.rNode instanceof BTreeNode) {
this.rNode = new BTreeNode(this.rNode);
}
if (!this.validate()) {
throw new Error("A BTree node must have a valid value, cannot be null or undefined");
}
}
/**
* Validates a BTree node, it must have a valid value (no undefined nor null).
* @public
* @returns {boolean}
* @example
* new BTreeNode(); // throws error saying `A BTree node must have a valid value, cannot be null or undefined`
* var node = new BTreeNode({ value: 10 });
* console.log(node.validate()); // true
*/
BTreeNode.prototype.validate = function () {
return (this.value != void 0 || this.value != null);
};
/**
* Converts current node and all children nodes in json format.
* @public
* @returns {BTreeNodeStruct}
* @example
* var node = new BTreeNode({ value: 10 });
* var lNode = new BTreeNode({ value: 15, lNode: lNode });
* console.log(node.toJSON()); // {value:15,lNode: {value: 10,lNode:null,rNode:null},rNode:null}
*/
BTreeNode.prototype.toJSON = function () {
var anyVal = this.value;
return {
value: (this.value && typeof anyVal.toJSON === "function") ? anyVal.toJSON() : this.value,
lNode: (this.lNode === null) ? null : this.lNode.toJSON(),
rNode: (this.rNode === null) ? null : this.rNode.toJSON()
};
};
/**
* Converts current node and all children nodes in json format and append them together.
* Goes in direction of U -> L -> R
* @public
* @returns {string}
* @example
* var node = new BTreeNode({ value: 10 });
* var lNode = new BTreeNode({ value: 15, lNode: node });
* console.log(node.toString()); // "1015"
*/
BTreeNode.prototype.toString = function () {
var anyVar = this.value;
var leftStr = (this.lNode === null) ? "" : this.lNode.toString();
var rightStr = (this.rNode === null) ? "" : this.rNode.toString();
var currStr = (typeof anyVar.toString === "function") ? anyVar.toString() : String(this.value);
return currStr + leftStr + rightStr;
};
/**
* Returns depth of its children.
* Goes in direction of L -> R
* @public
* @returns {number}
* @example
* var node = new BTreeNode({ value: 10 });
* var lNode = new BTreeNode({ value: 15, lNode: node });
* var l2Node = new BTreeNode({ value: 15, lNode: lNode });
* console.log(l2Node.getDepth()); // 3
*/
BTreeNode.prototype.getDepth = function () {
var leftDepth = (this.lNode === null) ? 1 : this.lNode.getDepth() + 1;
var rightDepth = (this.rNode === null) ? 1 : this.rNode.getDepth() + 1;
return Math.max(leftDepth, rightDepth);
};
return BTreeNode;
}());
exports.BTreeNode = BTreeNode;
if (typeof module != "undefined") {
module.exports = { BTreeNode: BTreeNode };
}
if (typeof window != "undefined") {
var modName = "DSinJS";
window.DSinJS = window.DSinJS || {};
window.DSinJS.BTreeNode = BTreeNode;
}
},{}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var btreenode_1 = require("./btreenode");
Object.defineProperty(exports, "BTreeNode", { enumerable: true, get: function () { return btreenode_1.BTreeNode; } });
var btree_1 = require("./btree");
Object.defineProperty(exports, "BTree", { enumerable: true, get: function () { return btree_1.BTree; } });
},{"./btree":1,"./btreenode":2}]},{},[3]);