JS散列表

散列表 HashTable

通过键值对储存的一种数据结构(key,value),通过键值(key)查找(value)。只查找一次,不需要n次遍历。查找时间为一个常量,即数据量的大小不会影响查找速度。
平均查找时间为O(1),对比二分法的查找时间为O(logn),线性查找为O(n)要快很多。
最坏情况查找时间情况下查找时间为线性时间O(n)。
数据增减和查找性能一致。也为O(1),O(n)。

性能受到以下因素影响:

  • 装填因子:已装填的数据/总容量,也就是空余位置越多,发生冲突可能性越小,性能越好。
  • 良好的散列函数 : 让数组中的值成均匀分布。尽量不要扎堆。

JS中的散列表

直接创建

最快的实现方式是直接创建对应格式

var a = new Array(); // or just []
a[0] = 0;
a['one'] = 1;
a['two'] = 2;
a['three'] = 3;

for (var k in a) {
    if (a.hasOwnProperty(k)) {
        console.log('key is: ' + k + ', value is: ' + a[k]);
          <!--  key is: 0, value is: 0
                key is: one, value is: 1 ... -->
    }
}
console.log(a.length); //1

但是这样有一问题,通过a.length可发现只有对数字的key有效,对string的key无效。
就是说a.length只计算了a[0]。因为js会在创建对象时,把key分为数字number a[0]或成员 memeber a['one']
而在计算长度时也就是indexed key,会忽略string的key。

自建HashTable

创建数组保存 var tabe = []
利用transHashCode把key转换成数字=每个字母的ASCII码值相加的除以37的余数
假设目标key是Jack,那么transHashCode(Jack)=5,增删查(put,get,remove)的目标就是table[5]

默认基本散列,但是没有考虑hash值重复。

function HashTable() {
    var table = [];
    var transHashCode = function (key) {
        var hash = 0;
        for (var i = 0; i < key.length; i++) {
            hash += key.charCodeAt(i); 
        }
        return hash % 37;
    };

    this.put = function(key, value) {
        var position = loseloseHashCode(key); 
        table[position] = value; 
    };

    this.get = function (key) {
        return table[loseloseHashCode(key)]; 
    };

    this.remove = function(key) {
        table[loseloseHashCode(key)] = undefined;
    };
}

当两个key的HASH值相等时,需要解决冲突。目前常用有 连接

  • 分离连接:在散列表每一个位置创建链表,也就是多个HASH值相等的key在同一个散列表位置下的不同链表。这样的问题是长度很难保持均衡。
  • 分离连接:出现重复后,通过位置+1的方式,排到后面位置。
  • 增加transHashCode的复杂度,来减少出现相同的情况。
    比如:
var djb2HashCode = function (key) {
    var hash = 5381; // 一个较大的素数基准值
    for (var i = 0; i < key.length; i++) {
        hash = hash * 33 + key.charCodeAt(i); // 基准值乘以33再加ASCII码值
    }
    return hash % 1013; //除以1013取余
};
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值