Algoritmo de búsqueda Hash (Hash) explicación detallada de la versión en lenguaje C

1. Principio del algoritmo de búsqueda hash

La búsqueda hash es un algoritmo de búsqueda rápida, este algoritmo no necesita comparar palabras clave, sino que utiliza palabras clave como variables independientes y la dirección de la palabra clave en el espacio de almacenamiento como variables dependientes para establecer una determinada relación funcional, llamada Es una función hash, para que al buscar una determinada palabra clave, su dirección se pueda obtener directamente a través de la función hash, lo que mejora efectivamente la eficiencia de la búsqueda.
La selección de la función hash y los principios básicos incluyen principalmente: el tiempo requerido para calcular la función, la longitud de la palabra clave, la longitud de la tabla hash (el rango de la dirección hash), la distribución de la palabra clave y la frecuencia de búsqueda del registro.
Hay muchas construcciones de funciones hash, como "método de direccionamiento directo", "método de análisis digital", "método cuadrado", "método de plegado", "método de resto", "método de números aleatorios", etc.
Un principio básico de la construcción de funciones hash es evitar conflictos tanto como sea posible, es decir, evitar conflictos de direcciones de variables dependientes tanto como sea posible. Una vez que se produce un conflicto, es necesario volver a abordar. Los métodos comunes para tratar los conflictos de direcciones incluyen: "método de direccionamiento abierto", "método de rehashing", "método de dirección en cadena", "establecimiento de un área de desbordamiento público", etc.

2. Ejemplo de creación de búsqueda hash y tabla de interpolación hash

Suponga que hay datos {10, 8, 14, 15, 20, 31}, cree una tabla hash para la búsqueda de hash.
1. Cree una tabla hash
Construya una función hash con el método de dividir el resto y utilice el método de detección lineal como método para tratar los conflictos. La longitud de la tabla hash se establece en 7. El proceso de establecimiento de la tabla hash es como sigue: H(10) = 10 % 7
= 3
H(8) = 8 % 7 = 1
H(14) = 14 % 7 = 0
H(15) = 15 % 7 = 1 Conflicto en este momento, re -dirección: H(15) = (H(15)+1 ) % 7 = 2
H(20) = 20 % 7 = 6
H(31) = 31 % 7 = 3 En este conflicto de tiempo, vuelva a dirigir: H (31) = (H(31)+1) % 7 = 4
ha La tabla es la siguiente:
inserte la descripción de la imagen aquí
2. Búsqueda hash
Al buscar un elemento, primero calcule su dirección hash a través de la función hash y luego compare si el valor de la dirección es igual al valor objetivo, si son iguales, la búsqueda finaliza; de lo contrario, use el método de manejo de conflictos para determinar la nueva dirección y luego compare. Si la dirección hash está vacía, la búsqueda falla.
Usar la función hash para calcular la dirección del elemento 15 es 1. En este momento, el elemento en la tabla no es igual a 15. Por lo tanto, el método de detección lineal se usa para actualizar la dirección hash y la nueva dirección es 2. En este momento, la búsqueda es exitosa.

3. Programa C del algoritmo de búsqueda de hash

Utilizando el "método restante" como función hash y el "método de detección lineal" como método para tratar los conflictos, proporcione el programa C para crear la tabla hash y el algoritmo de búsqueda hash.
1. La estructura de la tabla hash:
los miembros de la lista de miembros se pueden ajustar según las necesidades reales.

typedef struct HashTable
{
    
    
	int key;      //关键字 
	int EmptyFlag;//占用(冲突)标志,0表示没被占用,1表示被占用 
}HashTable;

2. Crea una tabla hash

//tbl:哈希表
//data:已知的数组
//m:数组的长度
//p:哈希表的长度 
void CreateHashTable( HashTable *tbl, int *data, int m, int p )
{
    
    
	int i, addr, k;
	for( i=0; i<p; i++ ) //把哈希表被占用标志置为0 
	{
    
    
		tbl[i].EmptyFlag = 0;
	}
	for( i=0; i<m; i++ )
	{
    
    
		addr = data[i] % p;//计算哈希地址 
		k = 0;//记录冲突次数 
		while( k++ < p )
		{
    
    
			if( tbl[addr].EmptyFlag == 0 )
			{
    
    
				tbl[addr].EmptyFlag = 1;//表示该位置已经被占用 
				tbl[addr].key   = data[i];
				break;
			}
			else
			{
    
    
				addr =  ( addr + 1 ) % p; //处理冲突 
			}
		}	
	}
}

3. Búsqueda de hash

int SearchHashTable( HashTable *tbl, int key, int p )
{
    
    
	int addr, k, loc;//loc表示查找位置下标,如果为0则表示查找失败 
	addr = key % P;//计算Hash地址 
	loc = -1; 
	k = 0;//记录冲突次数 
	while( k++ < p )
	{
    
    
		if( tbl[addr].key == key )
		{
    
    
			loc = addr;
			break;
		}
		else
		{
    
    
			addr =  ( addr + 1 ) % p; //处理冲突 
		}	
	}
	return loc;
}

3. Código de prueba completado

#include"stdio.h"
#define M 6
#define P (M+1)
typedef struct HashTable
{
    
    
	int key;      //关键字 
	int EmptyFlag;//占用(冲突)标志,0表示没被占用,1表示被占用 
}HashTable;

void CreateHashTable( HashTable *tbl, int *data, int m, int p );
int SearchHashTable( HashTable *tbl, int key, int p );

int main()
{
    
    
	HashTable HashTbl[P];
	int data[M] = {
    
     10, 8, 14, 15, 20, 31 };
	int i, loc;
	printf( "初始数据:\n" );
	for( i=0; i<M; i++ )
	{
    
    
		printf( "data[%d] = %5d\n", i, data[i] );
	}
	printf( "\n" );
	CreateHashTable( HashTbl, data, M, P );
	printf( "哈希表:  \n" );
	for( i=0; i<M; i++ )
	{
    
    
		printf( "tbl[%d] = %5d\n", i, HashTbl[i].key );
	}
	printf( "\n" );
	for( i=0; i<M; i++ )
	{
    
    
		loc = SearchHashTable( HashTbl, data[i], P );
		printf( "%5d 's loc = %5d\n", data[i], loc );
	}
	
	return 0;
}
void CreateHashTable( HashTable *tbl, int *data, int m, int p )
{
    
    
	int i, addr, k;
	for( i=0; i<p; i++ ) //把哈希表被占用标志置为0 
	{
    
    
		tbl[i].EmptyFlag = 0;
	}
	for( i=0; i<m; i++ )
	{
    
    
		addr = data[i] % p;//计算哈希地址 
		k = 0;//记录冲突次数 
		while( k++ < p )
		{
    
    
			if( tbl[addr].EmptyFlag == 0 )
			{
    
    
				tbl[addr].EmptyFlag = 1;//表示该位置已经被占用 
				tbl[addr].key   = data[i];
				break;
			}
			else
			{
    
    
				addr =  ( addr + 1 ) % p; //处理冲突 
			}
		}	
	}
}

int SearchHashTable( HashTable *tbl, int key, int p )
{
    
    
	int addr, k, loc;//loc表示查找位置下标,如果为0则表示查找失败 
	addr = key % P;//计算Hash地址 
	loc = -1; 
	k = 0;//记录冲突次数 
	while( k++ < p )
	{
    
    
		if( tbl[addr].key == key )
		{
    
    
			loc = addr;
			break;
		}
		else
		{
    
    
			addr =  ( addr + 1 ) % p; //处理冲突 
		}	
	}
	return loc;
}

4. Resultados de la prueba
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/sunnyoldman001/article/details/127345993
Recomendado
Clasificación