índice
1. Multiplicação contínua de poderes
2. Lei de Horner (Algoritmo Qin Jiushao)
3. Como conseguir uma distribuição uniforme.
Em segundo lugar, implemente a função hash
1. Excelente função hash
Antes de construir a tabela hash, precisamos de uma função hash para fazer o hash dos dados.
Então, como implementar essa função hash? De acordo com o blog anterior [estrutura de dados JS] para entender a tabela hash , já entendemos o que é uma tabela hash e por que precisamos projetar uma função hash.
Na verdade, é para atingir dois objetivos:
- Capacidade de calcular rapidamente e obter hashCode rapidamente
- Faça com que os elementos sejam distribuídos uniformemente na tabela hash.
1. Multiplicação contínua de poderes
Para o armazenamento de dados mencionado anteriormente, uma maneira é usar o poder da multiplicação para obter o hashCode
dar = 7 * 27 ^ 3 + 9 * 27 ^ 2 + 22 * 27 + 5 = 144941
Desta forma, é na verdade um polinômio, que pode ser reduzido a:
O número de multiplicações aqui é: n + (n-1) + ... + 1 = n (n + 1) / 2 vezes
O número de adições é: N vezes.
A complexidade de tempo obtida é (N ^ 2 + N) / 2 que é O (N ^ 2)
2. Lei de Horner (Algoritmo Qin Jiushao)
A lei de Horner é uma otimização de polinômios, de forma que o número de multiplicações seja reduzido, para que o hashCode seja obtido rapidamente, que se transforma na seguinte forma:
Tome como exemplo
O número de vezes de multiplicação aqui é: N vezes;
O número de adições é: N vezes.
A complexidade de tempo obtida é (N + N) ou O (N)
Portanto, o uso da lei de Horner pode melhorar muito a eficiência e reduzir o tempo de cálculo.
3. Como conseguir uma distribuição uniforme.
Ao projetar uma tabela hash, já temos dois métodos para lidar com mapeamentos para o mesmo valor subscrito, ou seja, para resolver conflitos, um é o método de endereço de cadeia e o outro é o método de endereço aberto.
Independentemente do método, é melhor distribuir os dados uniformemente na tabela de hash .
Então, quando usamos constantes, devemos usar números primos
1. O comprimento da tabela hash .
2. A base da enésima potência (37 é freqüentemente usado).
Os números primos são muito importantes, suponha que o comprimento da tabela seja 10 (o valor subscrito é 0 ~ 9)
Uma palavra-chave específica é mapeada para a posição onde o valor do subscrito é 0 e o tamanho do passo é 5, então a sequência de exploração será 0-5-0-5 ... e o ciclo continua.
Se o comprimento da tabela for 11, então a sequência a ser explorada é: 0-5-10-4-9-3-8-2-7-1-6, então não haverá loops e os dados podem ser na tabela de hash distribuída uniformemente.
Em segundo lugar, implemente a função hash
Projete uma função hash
1. Converta a string em um número relativamente grande para obter o hashCode.
2. Compacte este hashCode de grande número no intervalo do tamanho da matriz.
Dois parâmetros precisam ser passados, um é a string e o outro é o comprimento da tabela hash.
function hashFunc(str, size){
//定义一个变量来存储hashCode
var hashCode = 0;
// 利用霍纳法则计算出hashCode的值
// give -> Unicode编码
for (var i = 0; i < str.length; i++) {
hashCode = 37 * hashCode + str.charCodeAt(i);
}
// 利用hashCode与哈希表的长度取余得到下标值
var index = hashCode % size;
return index;
}
Código de teste:
//测试
alert(hashFunc('abc', 7)); // 4
alert(hashFunc('cla', 7)); // 2
alert(hashFunc('nbr', 7)); // 1
alert(hashFunc('kba', 7)); // 0
Resumo: uma boa função hash é mapear dados para locais diferentes o mais rápido possível .