在二叉搜索树

时间:2016-08-08 15:02:03

标签: javascript binary-search-tree

我希望有一组对象,按一些数字属性val排序。我希望能够检索匹配val与某些值匹配的所有对象,例如x,或者如果没有对象val匹配x,则查找对象距离val上方和下方最近的x。 (多个对象可能具有val

的相同值

我发现的为数不多的BST库之一是dsjslib。它具有所谓的TreeMultiMap,它为单个键保存多个值。问题是如果没有完全匹配,我无法看到如何检索最接近x的节点。

我怎么能这样做?浏览器对ES6的支持似乎有很长的路要走,所以也许我可以使用它的Map来做这个?

1 个答案:

答案 0 :(得分:0)

这听起来像是在二元搜索之后。我为Arrays开发了一个二进制findIndex方法,当然它在排序数组中工作。它需要一个回调,并且在它的帮助下,也可以搜索排序的对象数组。由于它是二进制搜索,因此比标准findIndexindexOf方法快得多。

默认回调是x => x,如果没有提供回调,它会默认处理已排序的原语。如果它找到搜索到的对象,它的当前状态会返回它的索引,但如果没有,它将返回-1。如果搜索到它可以很容易地修改以返回接近指数。如果您需要,我可以稍后再添加。

Array.prototype.sortedFindIndex = function(val, cb = x => x) { // default callback for primitive arrays
  var deli = this.length-1,                                    // delta index
      base = 0;                                                // base to add the delta index
  while (deli > 0 && cb(this[base + deli]) != val) {
    deli = ~~(deli/2);
    cb(this[base + deli]) < val && (base += deli);
  }
  return cb(this[base + deli]) === val ? base + deli : -1;
};

arr = [{a:0,b:"foo"},{a:1,b:"bar"},{a:2,b:"baz"},{a:3,b:"qux"},{a:4,b:"fox"},{a:5,b:"pun"},{a:6,b:"alf"}],
idx = arr.sortedFindIndex(4, o => o.a);

console.log(idx);

这是一个修改后的版本,可以更巧妙地处理故障情况。如果找不到搜索到的项目,则以下代码段将返回应该存在的索引的否定值。棘手的部分。如果缺少的项目应该插入索引0,它将返回负零(-0)。现在找到一个不存在的项目的上下接近应该是一块蛋糕。

Array.prototype.sortedFindIndex = function(val, cb = x => x) { // default callback for primitive arrays
  var            deli = this.length-1,                         // delta index
                 base = 0,                                     // base to add the delta index
      calculatedValue = cb(this[base + deli]),                 // use callback and get the value
           expectedAt = i => { while (this[i] !== void 0 && cb(this[i]) < val) ++i;
                               return -i};
  while (deli > 0 && calculatedValue != val) {
    deli = ~~(deli/2);
    (calculatedValue = cb(this[base + deli])) < val && (base += deli);
  }
  return calculatedValue === val ? base + deli : expectedAt(base + deli);
};

arr = [{a:0,b:"foo"},{a:1,b:"bar"},{a:2,b:"baz"},{a:3,b:"qux"},{a:4,b:"fox"},{a:5,b:"pun"},{a:6,b:"alf"},{a:7,b:"alf"},{a:8,b:"alf"},{a:9,b:"alf"},{a:10,b:"alf"},{a:11,b:"alf"},{a:13,b:"alf"}],
idx = arr.sortedFindIndex(12, o => o.a);

console.log(idx);