js数据结构——散列表

使用散列表的查找算法分为两步:
1. 散列函数将被查找的键转化为数组的一个索引。
2. 处理碰撞冲突(拉链法和线性探测法)

散列函数
  • 整数, 除数留余法:选择大小为素数M的数组,对于任一正整数k,计算k除以M的余数。
  • 浮点,如果键是0到1之间的实数,我们可以将它乘以M并四舍五入得到一个0至M-1之间的索引值。
  • 字符串, 除数留余
基于拉链法的散列表
class SeperateChainingHashST {
    constructor (M) {
        this.N = 0;//键值对总数
        this.M = M;//散列表大小
        this.st = [];
        for (let i = 0; i < M; i++){
            this.st[i] = new SequentialSearchST();
        }
    }
    hash (key) {
        return key%this.M;
    }
    put (key, value) {
        this.N++;
        this.st[this.hash(key)].put(key, value);
    }
    get (key) {
        return this.st[this.hash(key)].get(key);
    }
}
//顺序查找链表
class Node {
  constructor (key, value, next) {
    this.key = key;
    this.value = value;
    this.next = next;
  }
}
class SequentialSearchST {
  constructor () {
    this.first = null;
  }
  get (key) {
    let temp = this.first;
    while(temp && temp.key !== key) {
      temp = temp.next;
    }
    return temp && temp.value;
  }
  put (key, value){
    let temp = this.first;
    let prev =null;
    while(temp && temp.key !== key){
      prev = temp;
      temp = temp.next;
    }
    if(value !== undefined && temp == null ) {
      this.first = new Node(key, value, this.first);
      return;
    }
    if(value == undefined){
      if(prev === null){
        this.first =this.first && this.first.next;
      } else {
        prev.next = temp && temp.next;
      }
    }else{
      temp.value = value;
    }
  }
}
基于线性探测法的散列表

开放寻址类的散列表的核心思想是将散列表的空元素当做查找结束的标志。

class LinearProbingHashST  {
    constructor (M) {
        this.N = 0;
        this.M = M;
        this.keys = [];
        this.value = [];
    }
    hash (key) {
        return key%this.M;
    }
    put (key, value) {
        if(this.N >= this.M/2) this.resize(2 * this.M);
        let i;
        for(i = this.hash(key); this.keys[i] != undefined; i = (i + 1)%this.M ) {
            if(this.keys[i] === key){
                this.value[i] = value;
                return ;
            }
        }
        this.N++;
        this.keys[i] = key;
        this.value[i] = value;      
    }
    get (key) {
        for(i = this.hash(key); this.keys[i] != undefined; i = (i + 1)%this.M ) {
            if(this.keys[i] === key){
                return this.value[i];
            }
        }
        return null;
    }
    delete (key) {
        if(this.get(key) === null) return;
        let i = key%this.M;
        while(this.keys[i] != key){
            i = (i+1)%this.M;
        }
        this.keys[i] = null;
        this.value[i] = null;
        i = (i+1)%this.M;
        while(this.keys[i] != null){
            let newKey = this.keys[i];
            let newValue = this.value[i];
            this.keys[i] = null;
            this.value[i] = null;
            this.N--;
            this.put(newKey, newValue);
            i = (i+1)%this.M;
        }
        this.N--;
        if(this.N > 0 && this.N <=Math.ceil(this.M/8)) this.resize(Math.ceil(this.M/2))
    }
    resize (M) {
        this.M = M;
        let oldKeys = this.keys;
        let oldValue = this.value;
        this.keys = [];
        this.value = [];
        this.N = 0;
        for(let i in oldKeys) {
            this.put(oldKeys[i], oldValue[i]);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值