JS散列表

来源:互联网 发布:飞机pull up知乎 编辑:程序博客网 时间:2024/06/10 12:10

散列表 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取余};
原创粉丝点击