Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Binary Search #26

Open
barretlee opened this issue Jul 10, 2017 · 0 comments
Open

Binary Search #26

barretlee opened this issue Jul 10, 2017 · 0 comments

Comments

@barretlee
Copy link
Owner

#25 中提到的顺序查找,是通过 key 遍历查找链表拿到对应的 value,其插入动作也是一个查询的过程——找到了 key 就重置 value,否则在链表最前方插入节点。构建这种无序的链表,成本很低,但由于其数据结构的熵比较大,做大量操作时成本偏高,尤其是链表很长的时候。

二分查找(Binary Search),就需要我们在构建符号表的时候将数据结构规范化。通过一个数组来储存数据的 keys,然后在对应的另一个数组中储存 vals,通过下表将 key 和 val 意义对应起来。

而在构建符号表的时候,可以通过二分法就行处理,如:

/chapters/chapter-3-searching/3.1-elementary-symbol-tables/binarySearchST.js

function binarylSearchST() {
  var keys = [], vals = [];
  return {
    keys: keys,
    vals: vals,
    put: function(key, val) {
      var pos = this.rank(key);
      var N = keys.length;
      if(pos == 0) {
        keys[0] = key;
        vals[0] = val;
      }
      if(pos < N && keys[pos] === key) {
        vals[pos] = val;
        return;
      }
      for(var i = N; i >= pos + 1; i--) {
        keys[i + 1] = keys[i];
        vals[i + 1] = vals[i];
      }
      keys[i] = key;
      vals[i] = val;
    },
    get: function(key) {
      var pos = this.rank(key);
      if(pos >= 0) {
        return {
          key: keys[pos],
          val: vals[pos]
        }
      }
      return -1;
    },
    rank: function(key) {
      var start = 0, end = Math.max(keys.length - 1, 0), mid;
      while(start < end) {
        mid = ((end - start) >> 1) + start;
        if(!keys[mid]) return mid;
        if(keys[mid] < key) end = mid - 1;
        else if (keys[mid] > key) start = mid + 1;
        return mid;
      }
      return start;
    }
  }
}

使用 rank 方法,让我们在构建和查询符号表的时候,效率都特别高。在一个长度为 N 的有序数组中进行二分查找最多需要 lgN + 1 次比较,然而插入效率却有点低,一次插入最坏的效果是需要 ~2N 次访问数组,也就是说构建一个长度为 N 的符号表需要 ~N2 次访问,效率比 #25 更低。

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

1 participant