数据结构--散列(js版)

来源:互联网 发布:有房卡麻将源码自己做 编辑:程序博客网 时间:2024/06/05 10:42

散列是一种常用的数据储存技术,散列后的数据可以快速的插入或取用。我们的散列表是基于数组进行合计的,数组的长度是预先设定的。所有元素根据和改元素对应的键,保存在数组的特定位置。

  • 如果键是整型,最简单的散列函数就是以数组的长度对键取余–除留余数法。
  • 如果键是字符串类型,可以将字符串中每个字符的ASCII码相加再除以数组长度的取余。
  • 为了避免碰撞,首先要确保散列表中的用来储存数据的数据大小是一个质数。
function Hash(){    this.table = new Array(137);    this.simpleHash = simpleHash;    this.showDistro = showDistro;    this.push = push;    this.get = get;}function simpleHash(data) {    var total = 0;    for(var i=0;i<data.length;++i) {        total += data.charCodeAt(i)    }    return total % this.table.length;}function put(key,data) {    var pos = this.simpleHash(key);    this.table[pos] = data;}  function showDistro() {    var n = 0;    for(var i = 0; i < this.table.length; i++) {        if(this.table[i] !== undefined) {            console.log(i + ": " + this.table.[i])        }    }}function get(key) {    return this.table[this.simpleHash(key)]; }

多个输入的时候肯定会有碰撞发生的,发生碰撞后有两种解决方法,一个开链法、另一个是线性探测法。

开链法

  • 实现删列表中的底层数组中,每个元素又是另一个数组,这样就能存储多个键了。那么初始化Hash的时候就要先在初始化后调用bulidChains()。
  • 因为要区分她是哪个key,所以储存一个值得时候既要保存数据也要保存键值。 使用了两个连续的单元格,第一个用来保存键值,第二个保存数据。
function bulidChains() {    for(var i = 0; i < this.table.length; i++) {        this.table[i] = new Array();    }}function put(key,data) {     var pos = this.simpleHash(key);     if(this.table[pos][0] == undefined) {        this.table[pos][0] = key;        this.table[pos][1] = data;     }else {        var index = 2;        while(this.table[pos][index] != undefined) {            index += 2;        }        this.table[pos][index] = key;        this.table[pos][index+1] = data;    }}function get(key) {            var pos = this.simpleHash(key);    if(this.table[pos][0] == key) {        return this.table[pos][1];    }else {        var index = 2;        while(this.table[pos][index] != key && index <= this.table[pos].length) {            index += 2;;        }        return this.table[pos][index+1];    }}function showDistro() {    var n = 0;    for(var i = 0; i < this.table.length; i++) {        if(this.table[i][0] !== undefined) {            console.log(i + ": " + this.table[i])        }    }}var h = new Hash();h.bulidChains();h.push("grace",100);h.push("gray",88);h.showDistro();

线性探测法

当发生碰撞时,线性探测法检查散列表中的下一个位置是否为空。如果为空就存入该位置,如果不为空就继续检查下一个位置,直到找到空位置。这技术基于散列表有很多空的单元格。

//在Hash构造函数里加入this.value = new Array(137);      //用于存储数据function put(key,data) {    var pos = this.simpleHash(key);    if(this.table[pos] == undefined) {        this.table[pos] = key;;        this.value[pos] = data;    }else {        while(this.table[pos] != undefined) {            pos++;        }        this.table[pos] = key;        this.value[pos] = data;    }}function get(key) {    var pos = this.simpleHash(key);    for(var i = pos; this.table[pos] != undefined; i++) {        if(this.table[i] == key) {            return this.value[pos];        }    }    return undefined;}function showDistro() {    var n = 0;    for(var i = 0; i < this.table.length; i++) {        if(this.table[i] !== undefined) {            console.log(i + ": " + this.table[i]+"   "  + this.value[i])        }    }}
0 0
原创粉丝点击