Lenguaje C para lograr la tabla hash (método de cadena)

El autor aprendió recientemente la tabla hash en la estructura de datos y la implementó simplemente en lenguaje C.
Por supuesto, hay muchas referencias al código fuente, este blog está diseñado para intercambiar ideas

Principio de tabla hash

La estructura se describe de la siguiente manera:

typedef struct element
{
	int key;
	int value;
	int hash;
}Element;

Elemento representa el tipo de cada unidad de almacenamiento y es una estructura personalizada.
valor es el valor almacenado en Elemento (puede cambiarlo a otros).
clave es el valor clave utilizado para construir la tabla hash (el único valor que no se repite)
hash es el valor obtenido por la función hash.

typedef struct Pnode
{
	Element *data;
	struct Pnode *next;
}Node;

Nodo es un nodo de una lista vinculada individualmente.
Almacene
el campo del puntero junto al valor de Elemento y la siguiente dirección de nodo

typedef struct hash_table
{
	int size;
	int length;
	struct Pnode *head;
}Hash_table;

Hash_table es una estructura de tabla hash.
Almacene el tamaño del tamaño de la tabla hash (aquí relacionado con la función hash, el mío es REMAINDER = 11) y la longitud (número de elementos almacenados).
El campo de encabezado almacena la dirección del índice de matriz 0 en el lado izquierdo de la figura a continuación
Inserte la descripción de la imagen aquí
Nota: La forma de resolver el conflicto mediante el método de la cremallera es conectar el elemento conflictivo detrás del nodo que está en conflicto con él, formando así una sola lista vinculada.

Parte de la descripción de la función (que implica el uso de la función malloc y la operación de la lista individualmente vinculada):
Inicialización del encabezado de la tabla:

Hash_table* Creat_Table(int table_size)
{
	Hash_table *h = (Hash_table *)malloc(sizeof(Hash_table));
	h->size = REMAINDER;
	h->head = (Node *)malloc((h->size)*sizeof(Node));
	h->length = 0;
	int i = 0;
	for(i=0 ; i<h->size ; i++)
	{
		h->head[i].next = NULL;
	}
	return h;
}

Cree una tabla hash y devuelva el puntero del encabezado.
Al mismo tiempo, cree una matriz de longitud once para el campo de encabezado debajo del encabezado de la tabla y asigne la dirección del encabezado al encabezado.
Al mismo tiempo, inicialice la tabla, el tamaño se establece en REMAINDER 11, la longitud se establece en cero y el siguiente campo de cada nodo debajo del encabezado se le asigna un valor nulo (para evitar errores debido a razones del compilador).

Función de inserción: de
hecho, es más conveniente pasar la dirección de la estructura (no me di cuenta cuando era vago ...)

void Insert(Hash_table *h , Element k)
{
	Node * p = lookup(h,k.key);
	if(!p)
	{
		Node *q = (Node *)malloc(sizeof(Node));
		q->data = (Element *)malloc(sizeof(Element));
		(q->data)->key = k.key;
		(q->data)->value = k.value;
		int position;
		position = (q->data)->hash  = hash(k.key);
		q->next = h->head[position].next;
		h->head[position].next = q;
		
		h->length += 1; 
		return ;
	}
	else
	{
		printf("The keys is exist !\n");
		return ;
	}
}

Primero averigüe si el valor pasado ya está en la tabla hash (salga si existe).
Si no existe:
abra un nuevo campo Elemento y asígnele la estructura (no hay un pot para pasar la dirección, lo que resulta en una implementación aproximada, el lector puede probar un método más simple).
Y calcule el valor hash correspondiente a la clave, y El nodo se asigna a la posición especificada (que implica el funcionamiento de la lista individualmente vinculada).
Tenga en cuenta que si entra en conflicto o no, el método de implementación no cambia (este también es uno de los beneficios del método de cierre, y es fácil de insertar)

Función de búsqueda:

Node *lookup(Hash_table *h , int key)
{
	int i;
	i = hash(key);
	Node * p = h->head[i].next;
	while(p && key != p->data->key)
	{
		p = p->next;
	}

	return p;
}

Primero calcule el valor hash correspondiente al valor clave, y verifique los nodos de la lista enlazada individualmente en la posición correspondiente uno por uno, y devuelva sus direcciones.

El código fuente es el siguiente:

#include<stdio.h>
#include<stdlib.h>

#define REMAINDER 11	// 通常是质数

typedef struct element
{
	int key;		
	int value;
	int hash;
}Element;

typedef struct Pnode
{
	Element *data;
	struct Pnode *next;
}Node;

typedef struct hash_table
{
	int size;
	int length;
	struct Pnode *head;
}Hash_table;


int hash(int value)
{
	return value%REMAINDER;
}

Hash_table* Creat_Table(int table_size)
{
	Hash_table *h = (Hash_table *)malloc(sizeof(Hash_table));
	h->size = REMAINDER;
	h->head = (Node *)malloc((h->size)*sizeof(Node));
	h->length = 0;
	int i = 0;
	for(i=0 ; i<h->size ; i++)
	{
		h->head[i].next = NULL;
	}
	return h;
}

Node *lookup(Hash_table *h , int key)
{
	int i;
	i = hash(key);
	Node * p = h->head[i].next;
	while(p && key != p->data->key)
	{
		p = p->next;
	}

	return p;
}

void Insert(Hash_table *h , Element k)
{
	Node * p = lookup(h,k.key);
	if(!p)
	{
		Node *q = (Node *)malloc(sizeof(Node));
		q->data = (Element *)malloc(sizeof(Element));
		(q->data)->key = k.key;
		(q->data)->value = k.value;
		int position;
		position = (q->data)->hash  = hash(k.key);
		q->next = h->head[position].next;
		h->head[position].next = q;
		
		h->length += 1; 
		return ;
	}
	else
	{
		printf("The keys is exist !\n");
		return ;
	}
}

void Destroy_Table(Hash_table *h)
{
	int i;
	Node *p , *q;
	for(i=0 ; i<h->size ; i++)
	{
		p = h->head[i].next;
		while(p)
		{
			q=p->next;
			free(p);
			p=q;
		}
	}
	free(h->head);
	free(h);
}

void print_Table(Hash_table *h)
{
	int i = 0; 
	for (i = 0; i < h->size ; i++)
    {
        Node * p = h->head[i].next;
        while (p)
        {
            printf("[%d-%d] ",p->data->key, p->data->value);
            p = p->next;
        }
        printf("NULL\n");
    }
}

int main()
{
	Element a[]={{12,1},{2,2},{31,3},{45,4},{8,5}};
	
	int n = sizeof(a)/sizeof(Element);
	Hash_table *h = Creat_Table(n);
	int i = 0;
	for(i = 0 ; i<n ; i++)
	{
		Insert(h,a[i]);
	}
	print_Table(h);		// 打印哈希表 
	printf("%d\n\n", lookup(h,12)->data->key);	//查找key值为12的Element  
	printf("%d\n",h->length);	//打印哈希表的元素个数 
	Destroy_Table(h);	// 摧毁哈希表 
	return 0;
}

Captura de pantalla del código fuente:

Publicado 7 artículos originales · ganó 12 · vistas 775

Supongo que te gusta

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