Linguagem C para implementar tabela de hash (método de endereço aberto)

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:
Insira a descrição da imagem aqui

Obrigado por assistir ~

Publicado 7 artigos originais · ganhou 12 · visualizações 774

Acho que você gosta

Origin blog.csdn.net/M_H_T__/article/details/103263414
Recomendado
Clasificación