使用javascript模拟常见数据结构(三)

六、字典和散列表   

  我们已经知道,集合表示一组互不相同的元素(不重复元素)。在字典中,存储的是键值对,其中键值是用来查询特定的元素的。字典和集合是很相似的,集合采用[值,值]的方式存储,而字典则是以[键,值]的方式来进行存储的。字典也称作映射。

  首先,我们还是用函数来创建一个字典,在es6中新增了map类,其表示的就是字典这种数据结构。

  

function Dictionary(){
     var items = {};      
}

嗯,然后其实还是老规矩,有一些方法来操作这个字典,包括set,remove,has,get,clear等等。

this.has = function(key){
     return key in items;
}
this.set = function(key,value){
    items[key] = value      
}
this.remove = function(key){
    if(this.has(key)){
        delete items[key];
        return true
    }
    return null    
}
this.get = function(){
    return this.has[key]?item[key]:undefined;
}

  嗯,主要就是上述这些方法,其实简单来说就是个对象。。。。

  下面主要来说一下散列表,叫做HashTable或者HashMap,散列表可以明显提高字典的查找速度,简而言之就是它不需要去遍历键。对于没哟个键名,它使用了一种算法来进行编码,编码的值记录了值的地址,嗯,像下面这张图一样。

  

  嗯,上面这张图是根据键名每个字母的ASCⅡ码的和来进行的,实际情况其实要比这复杂的多。

  然后我们可以根据loselose算法来进行键名和散列值的对应:

  

var loseloseHashCode = function (key) {
        var hash = 0; 
        for (var i = 0; i < key.length; i++) { 
        hash += key.charCodeAt(i); 
        }
        return hash % 37; 
};

  嗯,这样就变成了下图这个样子了。

  

  嗯,这样需要的数组的长度就比上面小的多了,并且,如果我们需要查找一个key,那么就可以很容易的通过上面的算法直接找到其对应的值,而不用遍历整个字典了。

  另外,在散列表中大家也可以很容易的想到,如果键名生成了同样的散列值怎么样,比如Tyrion 和Aaron会生成同样的散列值16,这样后输入的键值就会覆盖前面的键值,为了解决这个问题,我们可以使用分离链表来解决。如下图:

  

  

  这样在一个散列表的每一个值的位置我们都存储一个链表,就不会发生上面说的那种情况了,这种方法叫做分离链表。

posted @ 2017-05-07 17:43  史聪  阅读(216)  评论(0编辑  收藏  举报