Skip to content

Commit 7471dff

Browse files
author
Bishop92
committed
Added methods fullContains and cloneDistinct
1 parent ab7d0e3 commit 7471dff

File tree

2 files changed

+148
-13
lines changed

2 files changed

+148
-13
lines changed

BTree/BTree.js

Lines changed: 147 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,17 @@ BTree.prototype.insertNonFull = function (node, key, item) {
117117
};
118118

119119
/**
120-
* Search the item relatives to the key.
120+
* Search the item relatives to the key that satisfy the condition represented by the callback function.
121121
* @param key {Number} The key to find.
122122
* @param [node = root] {RBNode} The node from which start the search.
123+
* @param [callback = function(node,index){return(node.keys[index]===key);}] The condition to satisfy. The callback must accept the current node to check and optionally the position of the key.
123124
* @return {*} The item found or undefined if there isn't the key in the tree.
124125
*/
125-
BTree.prototype.search = function (key, node) {
126+
BTree.prototype.search = function (key, node, callback) {
126127
node = node || this.root;
128+
callback = callback || function (node, index) {
129+
return node.keys[index] === key;
130+
};
127131
while (node) {
128132
var n = node.keys.length;
129133
var i = 0, j = n;
@@ -134,7 +138,7 @@ BTree.prototype.search = function (key, node) {
134138
else
135139
i = m + 1;
136140
}
137-
if (i < n && key === node.keys[i])
141+
if (i < n && callback(node, i))
138142
return node.items[i];
139143
else if (!node.childs.length)
140144
return undefined;
@@ -354,10 +358,24 @@ BTree.prototype.augmentChild = function (node, index) {
354358
/**
355359
* Checks if the tree contains the key.
356360
* @param key {number} The key to find.
361+
* @param [callback = function(node,index){return(node.keys[index]===key);}] The condition to satisfy. The callback must accept the current node to check and optionally the position of the key.
357362
* @return {boolean} True if the tree contains the key.
358363
*/
359-
BTree.prototype.contains = function (key) {
360-
return this.search(key) !== undefined;
364+
BTree.prototype.contains = function (key, callback) {
365+
return this.search(key, null, callback) !== undefined;
366+
};
367+
368+
/**
369+
* Checks if the tree contains a node that satisfy the condition represented by the callback function.
370+
* This method check all the tree avoiding the binary search.
371+
* @param callback {function} The condition to satisfy. The callback must accept the current node to check.
372+
* @return {boolean} True if the tree contains the node that satisfy the condition, false otherwise.
373+
*/
374+
BTree.prototype.fullContains = function (callback) {
375+
var key = this.minimumKey();
376+
while (key !== null && !callback(this.search(key)))
377+
key = this.successor(key);
378+
return key !== null;
361379
};
362380

363381
/**
@@ -439,18 +457,22 @@ BTree.prototype.minimumKey = function () {
439457
var node = this.root;
440458
while (node.childs.length)
441459
node = node.childs[0];
442-
return node.keys[0];
460+
if (node)
461+
return node.keys[0];
462+
return null;
443463
};
444464

445465
/**
446466
* Gets the maximum key stored in the tree.
447-
* @return {node} The key found.
467+
* @return {number} The key found.
448468
*/
449469
BTree.prototype.maximumKey = function () {
450470
var node = this.root;
451471
while (node.childs.length)
452472
node = node.childs[node.childs.length - 1];
453-
return node.keys[node.keys - 1];
473+
if (node)
474+
return node.keys[node.keys.length - 1];
475+
return null;
454476
};
455477

456478
/**
@@ -472,7 +494,7 @@ BTree.prototype.maximum = function () {
472494
var node = this.root;
473495
while (node.childs.length)
474496
node = node.childs[node.childs.length - 1];
475-
return node.items[node.items - 1];
497+
return node.items[node.items.length - 1];
476498
};
477499

478500
/**
@@ -522,11 +544,14 @@ BTree.prototype.clear = function () {
522544
BTree.prototype.filter = function (callback) {
523545
var result = [];
524546
var node = arguments[1] || this.root;
525-
for (var i = 0; i < node.items.length; i++)
547+
for (var i = 0; i < node.items.length; i++) {
548+
if (node.childs.length)
549+
result = result.concat(this.filter(callback, node.childs[i]));
526550
if (callback(node.items[i]))
527551
result.push(node.items[i]);
528-
for (var j = 0; j < node.childs.length; j++)
529-
result.concat(this.filter(callback, node.childs[j]));
552+
}
553+
if (node.childs.length)
554+
result = result.concat(this.filter(callback, node.childs[node.childs.length - 1]));
530555
return result;
531556
};
532557

@@ -544,4 +569,114 @@ BTree.prototype.clone = function () {
544569
tree.insert(it.getKey(), item);
545570
}
546571
return tree;
572+
};
573+
574+
/**
575+
* Clones the tree into a new tree without cloning duplicated items.
576+
* @return {BTree} The tree cloned from this tree.
577+
*/
578+
BTree.prototype.cloneDistinct = function () {
579+
var tree = new BTree(this.t);
580+
var it = this.getIterator();
581+
for (it.first(); !it.isDone(); it.next()) {
582+
var callback = function (item) {
583+
return item === it.getItem();
584+
};
585+
if (!tree.fullContains(callback)) {
586+
if (it.getItem().cloneDistinct)
587+
tree.insert(it.getKey(), it.getItem().cloneDistinct());
588+
else if (it.getItem().clone)
589+
tree.insert(it.getKey(), it.getItem().clone());
590+
else
591+
tree.insert(it.getKey(), it.getItem());
592+
}
593+
}
594+
return tree;
595+
};
596+
597+
/**
598+
* Transform the tree into an array without preserving keys.
599+
* @return {Array<*>} The array that represents the tree.
600+
*/
601+
BTree.prototype.toArray = function () {
602+
var result = [];
603+
var it = this.getIterator();
604+
for (it.first(); !it.isDone(); it.next())
605+
result.push(it.getItem());
606+
return result;
607+
};
608+
609+
/**
610+
* Returns the first position of the item in the tree.
611+
* @param item {*} The item to search.
612+
* @param [callback = function(item){return(it===item);}] The condition to satisfy. The callback must accept the current item to check.
613+
* @return {number} The first position of the item.
614+
*/
615+
BTree.prototype.indexOf = function (item, callback) {
616+
callback = callback || function (it) {
617+
return it === item;
618+
};
619+
var i = 0, key = this.minimumKey();
620+
while (key !== null) {
621+
if (callback(this.search(key)))
622+
return i;
623+
key = this.successor(key);
624+
i++;
625+
}
626+
return -1;
627+
};
628+
629+
/**
630+
* Returns the last position of the item in the tree.
631+
* @param item {*} The item to search.
632+
* @param [callback = function(item){return(it===item);}] The condition to satisfy. The callback must accept the current item to check.
633+
* @return {number} The last position of the item.
634+
*/
635+
BTree.prototype.lastIndexOf = function (item, callback) {
636+
callback = callback || function (it) {
637+
return it === item;
638+
};
639+
var i = this.size - 1, key = this.maximumKey();
640+
while (key !== null) {
641+
if (callback(this.search(key)))
642+
return i;
643+
i--;
644+
key = this.predecessor(key);
645+
}
646+
return -1;
647+
};
648+
649+
/**
650+
* Returns all the position in which the item has been found in the tree.
651+
* @param item {*} The item to search.
652+
* @param [callback = function(item){return(it===item);}] The condition to satisfy. The callback must accept the current item to check.
653+
* @return {Array<number>} The positions in which the item has been found.
654+
*/
655+
BTree.prototype.allIndexesOf = function (item, callback) {
656+
callback = callback || function (it) {
657+
return it === item;
658+
};
659+
var i = 0, key = this.minimumKey();
660+
var indexes = [];
661+
while (key !== null) {
662+
if (callback(this.search(key)))
663+
indexes.push(i);
664+
i++;
665+
key = this.successor(key);
666+
}
667+
return indexes;
668+
};
669+
670+
/**
671+
* Returns the item at the position index.
672+
* @param index {number} The position of the item.
673+
* @return {*} The item at the position. It's undefined if index isn't in the tree bounds.
674+
*/
675+
BTree.prototype.getItem = function (index) {
676+
if (index < 0 || index > this.size - 1)
677+
return undefined;
678+
var key = this.minimum();
679+
for (var i = 0; i < index; i++)
680+
key = this.successor(key);
681+
return this.search(key);
547682
};

BTree/BTreeIterator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ BTreeIterator.prototype.previous = function () {
5656
* @inheritDoc
5757
*/
5858
BTreeIterator.prototype.isDone = function () {
59-
return !this.pointer;
59+
return this.pointer === null;
6060
};
6161

6262
/**

0 commit comments

Comments
 (0)