散列:
快速插入、取用和删除
查找数据低下,如最大值和最小值
质数:素数也指的是质数,除了1和它本身,没有其他因子
代码示例:
通过传入字符串的uniCode或优化过uniCode的编码总和%字符串的长度,来获取散列的索引值,来存储内容
增大散列值解决位置冲突:
function HashTable() {
this.table = new Array(137);
this.simpleHash = simpleHash; //计算散列位置辅助函数,计算出所有字符串的unicode值,但相同字符不同位置的字符串会得出相同结果
this.betterHash = betterHash;//增大散列值后的辅助函数
this.display = display;//遍历
this.put = put;//插入元素
this.get = get;//获取元素
}
function simpleHash(data) { //计算键位置的辅助函数
let total = 0;
for (let i = 0; i < data.length; i++){
total += data.charCodeAt(i); //计算出所有字符串的unicode值,但相同字符不同位置的字符串会得出相同结果
}
return total % this.table.length; //散列函数除留余数法
}
function betterHash(data) {
let total = 0;
let H = 31; //手动设定一个值,将unicode计算得出的值更散列,即使得相同字符不同位置的字符串,得出的结果相同概率减少
for (let i = 0; i < data.length; i++){
total +=H*total+ data.charCodeAt(i); //计算出所有字符串的unicode值
}
return total % this.table.length; //散列函数除留余数法
}
function put(data) {
//let pos = this.simpleHash(data);
let pos = this.betterHash(data); //方式一:增大散列值
this.table[pos] = data;
}
function get(key) {
//return this.simpleHash(key);
return this.betterHash(key);
}
function display() {
var n;
for (var i = 0; i < this.table.length; i++){
if (this.table[i]!= undefined) {
console.log("键值是->" + i + "值是" + this.table[i]);
}
}
}
let hTable = new HashTable();
hTable.buildChains();
hTable.put('china'); //会和nicha的unicode值重复,因为字符都是相同的
hTable.put('jeff');
hTable.put('jack');
hTable.put('nicha');
hTable.put('tom');
hTable.put('12344');
hTable.display();
开链法解决冲突:
将存储的数组变成二维数组,如果unicode值相同,则往对应数组后挪一位存储,[[1,冲突2],[…],[…]]
function HashTable() {
this.table = new Array(137);
this.simpleHash = simpleHash;
this.buildChains = buildChains;
this.display = display;
this.put = put;
this.get = get;
}
//开链法,即升级为二维数组
function buildChains() {
console.log(this.table)
for (let i = 0; i < this.table.length; i++){
this.table[i] = new Array();
}
}
function simpleHash(data) { //计算键位置的辅助函数
let total = 0;
for (let i = 0; i < data.length; i++){
total += data.charCodeAt(i); //计算出所有字符串的unicode值,但相同字符不同位置的字符串会得出相同结果
}
return total % this.table.length; //散列函数除留余数法
}
function put(data) {
let pos = this.simpleHash(data);
let index = 0;
if (this.table[pos][index] == undefined) {
this.table[pos][index] = data;
index++;
} else {
while (this.table[pos][index] !== undefined) {//若存储冲突,往后挪一位
index++;
}
this.table[pos][index] = data;
index++;
}
}
function get(key) {
return this.simpleHash(key);
}
function display() {
var n;
for (var i = 0; i < this.table.length; i++){
if (this.table[i][0] != undefined) {
console.log("键值是->" + i + "值是" + this.table[i]);
}
}
}
let hTable = new HashTable();
hTable.buildChains(); //将一维数组变成二维数组
hTable.put('china'); //会和nicha的unicode值重复,因为字符都是相同的
hTable.put('jeff');
hTable.put('jack');
hTable.put('nicha');
hTable.put('tom');
hTable.put('12344');
hTable.display();
线性探测法解决冲突:
如果数组当前位置存储冲突,则移动到下一个位置存储,同时还需修改返回散列值的get方法,不能单纯地返回对应simpleHash,因为可能相同值冲突,真正值往后移了
function HashTable() {
this.table = new Array(137);
this.simpleHash = simpleHash;
this.display = display;
this.put = put;
this.get = get;
}
function simpleHash(data) { //计算键位置的辅助函数
let total = 0;
for (let i = 0; i < data.length; i++){
total += data.charCodeAt(i); //计算出所有字符串的unicode值,但相同字符不同位置的字符串会得出相同结果
}
return total % this.table.length; //散列函数除留余数法
}
function put(data) {
let pos = this.simpleHash(data);
while (this.table[pos] != undefined) { //线性探测,如果当前位置有值,往后移动
pos++;
}
this.table[pos] = data;
}
function get(key) { //修改返回散列值方法,不能单纯地返回对应simpleHash,因为可能相同值冲突,真正值往后移了
for (i = 0; i < this.table.length; i++){
if (this.table[i] == key) {
return i;
}
}
}
function display() {
var n;
for (var i = 0; i < this.table.length; i++){
if (this.table[i]!= undefined) {
console.log("键值是->" + i + "值是" + this.table[i]);
}
}
}
let hTable = new HashTable();
hTable.put('china'); //会和nicha的unicode值重复,因为字符都是相同的
hTable.put('jeff');
hTable.put('jack');
hTable.put('nicha');
hTable.put('tom');
hTable.put('12344');
hTable.display();
console.log('位置:'+hTable.get('nicha'))