雜湊表(散列表):通過雜湊函式將鍵值對映為一個字典;

雜湊函式:依賴鍵值的資料型別來構建一個雜湊函式;

一個基本的雜湊表:(按字串計算鍵值)

function HashTable() {
this.table = new Array(137);
this.simpleHash = simpleHash;
this.showDistro = showDistro;
this.put = put;
this.init = init;
}
function simpleHash(data) {
var total = 0;
for(var i = 0; i < data.length; ++i) {
total += data.charCodeAt(i);
}
return total % this.table.length;
}
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 put(data) {
var pos = this.simpleHash(data);
this.table[pos] = data;
}
function init(data) {
for(var i = 0; i < data.length; ++i) {
this.put(data[i]);
}
}

操作:demo:;

可能出現的問題:

  • 碰撞;即在雜湊函式計算的時候出現相同的雜湊值;
  • 解決:這要解決雜湊函式的計算問題;如上面定義中雜湊函式,是求餘計算:這裡首先確保陣列大小為質數(求餘);大小應該在100以上(分佈均勻);

上例中使用霍納演算法:求和時每次乘以一個較小的質數;

function betterHash(string) {
var H = 37;
var total = 0;
for(var i = 0; i < string.length; ++i) {
total = H * total + string.charCodeAt(i);
}
total = total % this.table.length;
if(total < 0) {
total += this.table.length-1;
}
return parseInt(total);
}

 雜湊化整型鍵:

  • 隨機生成id+score的數字:
 function getRandomInt(min,max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function genStuData(arr) {
for(var i = 0; i < arr.length; ++i) {
var num = "";
for(var j = 0; j < 6; ++j) { //id : length - 6;
num += Math.floor(Math.random() * 10);
}
num += getRandomInt(50,100);
arr[i] = num;
}
}
  • 操作:demo;  經測試betterHash不但對字元,對整數型別也是有更好的效果;

碰撞處理:

  • 開鏈法:(利用二維陣列)

修改:
function put(data) {
var pos = this.simpleHash(data);
this.table[pos].push(data);
}
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]);
}
}
}
新增:
function builChains() {
for(var i = 0; i < this.table.length; ++i) {
this.table[i] = new Array();
}
}

  

操作:demo

  • 線性探測法:發生碰撞時依次向下儲存;
修改:
function put(data) {
var pos = this.simpleHash(data);
while(this.table[pos] !== undefined) {
++pos;
}
this.table[pos] = data;
}

一般而言:如果陣列大小是要儲存資料的2倍及以上,使用線性探測法。