O autor aprendeu recentemente a tabela de hash na estrutura de dados e a implementou simplesmente na linguagem C.
Este blog foi criado para trocar idéias.
Este blog apresenta uma tabela de hash construída pelo método de endereço aberto
O princípio da tabela de hash pode consultar este artigo: Introdução ao princípio da tabela de hash
Se você deseja consultar a tabela de hash criada pelo método zipper, consulte este artigo: Linguagem C para implementar a tabela de hash (método zipper)
Descrição da estrutura
typedef struct element
{
int key; // key值 唯一不重复
int data; // data 域
}Element;
O campo de dados pode ser alterado para uma estrutura personalizada (é claro, parte do código da função principal subsequente precisa ser modificada de acordo) O
valor da chave é calculado pela função hash e um endereço mapeado é obtido
typedef struct table
{
Element **elm; //
int count; // 记录表中记录的数据个数
int size; // 哈希表的大小 = SIZE = 50
}Table;
Nota: elm é um ponteiro para uma matriz de estruturas de elemento de ponteiro (por favor, entenda bem), isto é, uma matriz de ponteiro do tipo Elemento é criada e elm aponta para o endereço principal dessa matriz, por isso é declarado como um ponteiro de segundo nível (ponteiro para ponteiro) .
Parte da descrição da função:
crie uma função de tabela de hash:
Table * init_Table()
{
Table *t = (Table*)malloc(sizeof(Table));
t->size = REMAINDER;
t->count = 0;
t->elm = (Element **)malloc(SIZE*sizeof(Element*));
/*
创建一个长度为13的指针数组,类型为Element*
并将数组头地址赋值给 elm 的二级指针
*/
int i;
for(i=0 ; i<t->size ; i++)
{
t->elm[i] = NULL; // 将数组的每个域赋空
}
return t;
}
Declare uma variável do tipo Tabela, crie espaço para ela e retorne seu endereço.
Durante a inicialização, preste atenção na inicialização de variáveis do tipo ponteiro (alguns compiladores o ajudarão a esvaziar, outros não)
Inserir função
void Insert(Table *t,Element * k) //将key值插入到哈希表中
{
int i;
int position;
position = hash(k->key);
for(i=1 ; t->elm[position]!=NULL && i<t->size ;i++ )
{
position=(hash(position)+i)%t->size;
}
t->elm[position] = k;
t->count += 1;
return ;
}
A forma geral do método de endereço aberto é:
H (tecla) é uma função de hash, m é o comprimento da tabela.Este
método é fácil de causar empilhamento. A solução é melhorar a função de hash ou usar o método de zíper (cada um tem vantagens e desvantagens).
Encontre a função:
int serch(Table *t, Element * k) //查找 value 并返回其所在的地址
{
int position=hash(k->key);
while(t->elm[position]->key != k->key)
{
position = hash(position+1);
if(t->elm[position]==NULL || position == hash(k->key))
/*
出现以下几种情况即判断查找失败
1.对应的 position 位置的地址为空
2.遍历整个表都没有对应的 key 值
*/
return -1;
}
return position;
}
As seguintes situações ocorrem quando a pesquisa falha
1. O endereço da posição correspondente está vazio
2. Não há um valor de chave correspondente para percorrer a tabela inteira
Código completo:
#include<stdio.h>
#include<stdlib.h>
#define REMAINDER 13
#define SIZE 50
typedef struct element
{
int key; // key值 唯一不重复
int data; // data 域
}Element;
typedef struct table
{
Element **elm; //
int count; // 记录表中记录的数据个数
int size; // 哈希表的大小 = SIZE = 50
}Table;
int hash(int key)
{
return key%REMAINDER;
}
Table * init_Table()
{
Table *t = (Table*)malloc(sizeof(Table));
t->size = SIZE;
t->count = 0;
t->elm = (Element **)malloc(SIZE*sizeof(Element*));
/*
创建一个长度为13的指针数组,类型为Element*
并将数组头地址赋值给 elm 的二级指针
*/
int i;
for(i=0 ; i<t->size ; i++)
{
t->elm[i] = NULL; // 将数组的每个域赋空
}
return t;
}
void Insert(Table *t,Element * k) //将key值插入到哈希表中
{
int i=0;
int position;
position = hash(k->key);
for(i=1 ; t->elm[position]!=NULL && i<t->size ;i++ )
{
position=(hash(position)+i)%t->size;
}
t->elm[position] = k;
t->count += 1;
return ;
}
int serch(Table *t, Element * k) //查找 value 并返回其所在的地址
{
int position=hash(k->key);
while(t->elm[position]->key != k->key)
{
position = hash(position+1);
if(t->elm[position]==NULL || position == hash(k->key))
/*
出现以下几种情况即判断查找失败
1.对应的 position 位置的地址为空
2.遍历整个表都没有对应的 key 值
*/
return -1;
}
return position;
}
void Print_Table(Table *t) //打印部分哈希表
{
int i;
for(i=0 ; i<13 ; i++)
{
if(t->elm[i])
printf("[%d %d] ",t->elm[i]->key , t->elm[i]->data);
else printf("NULL ");
}
printf("\n");
}
int main()
{
Table *t = init_Table();
Element a[]={{12,99},{13,98},{26,87},{14,77},{15,100},{10,59}};
int length = sizeof(a)/sizeof(Element);
int i;
for(i=0 ; i<length ; i++)
{
Insert(t,&a[i]);
}
Print_Table(t);
printf("a[3] is locat %d\n",serch(t,&a[3]));
free(t);
}
Executar captura de tela:
Obrigado por assistir ~