Como evitar redimensionamentos em cascata ao redimensionar tabelas de hash?

8

Com métodos convencionais de resolução de colisões, como encadeamento separado e sondagem linear / quadrática, a sequência da sonda para uma chave pode ser arbitrariamente longa - ela é simplesmente mantida curta com alta probabilidade, mantendo o fator de carga da tabela baixo. As colisões durante a reaplicação, portanto, não são um problema, pois não afetam o fator de carga.

No entanto, com o hash do cuco (e outros métodos que oferecem o pior tempo de pesquisa O (1)?), Um redimensionamento deve ocorrer quando a sequência de análise de uma chave fica muito longa. Mas quando as chaves são embaralhadas durante a repetição, pode ser que elas criem uma sequência de sondagem muito longa para uma chave, necessitando de outro redimensionamento - possivelmente várias, se isso acontecer várias vezes seguidas. A probabilidade é pequena, especialmente com uma boa função de hash, mas já vi isso acontecer.

Existe uma maneira - além de gerar explicitamente uma função de hash perfeita durante a reformulação - para garantir que os redimensionamentos não possam ser cascateados dessa maneira? Possivelmente específico para um determinado esquema de resolução de colisões? A literatura que encontrei até agora parece encobrir completamente o assunto. Lembre-se de que eu também estou interessado em reduzir tabelas de hash, não apenas cultivá-las.

Anônimo
fonte

Respostas:

1

Você pergunta como evitar repetições em cascata, mas você já deu a resposta em sua postagem. Você mantém a probabilidade de que eventos ruins ocorram pequenos.

Desde que você mencionou o hash do cuco. A probabilidade de você obter uma longa sequência de sondagem é . Portanto, se você repetir, está inserindo elementos do zero. A probabilidade de que a rehash não seja bem-sucedida é , portanto, com uma probabilidade muito alta, você é bem-sucedido. Na expectativa, você precisa apenas de um número constante de tentativas. Se você observar que tem problemas com a reforma, deverá aumentar o tamanho da tabela e modificar o fator de carga. Como alternativa, você pode selecionar uma família melhor de funções de hash.O(1/n2)nO(1/n)

A.Schulz
fonte
-1

Acredito que tenho uma solução, inspirada no hash linear :

Se a (s) função (s) de hash for mantida constante (ou seja, não alterada ao redimensionar) e a tabela for sempre aumentada dobrando os slots, depois que a tabela for aumentada, isso significa que

Hmod2eu={Hmodeu+euouHmodeu

onde é o hash de uma chave e é o número antigo de slots. Isso significa que uma chave permanece onde está ou se move para um slot exclusivo na área recém-alocada, que é garantida como vazia.Heu

Para aplicar isso ao hash do cuco (d-ário), basta redimensionar cada uma das subtabelas individualmente e não mova as teclas entre as subtabelas.

Para reduzir a tabela, você precisa confirmar que um dos está vago para todas as chaves da tabela e, em caso afirmativo, mova todas elas para seus slots . Claro, esse é ... Não tenho certeza se há uma maneira melhor de fazer isso do que executar a verificação para cada exclusão, uma vez que o fator de carga cai abaixo da metade.{Hmodeu2+eu2, Hmodeu2}Hmodeu2O(n)

Anônimo
fonte
Não tenho certeza se isso funciona. E se a sua função hash for h (x) = c, para alguma constante c?
Jbapple # 6/14