C语言实现哈希表

除留余数法 + 线性探测。

#include 
#include 
#include 
#include 
#include 
#include 


#define NOT_FOUND   -1
#define EMPTY   -1


void *Malloc (size_t size)
{
	void *mem = malloc (size);
	if (mem == NULL)
		err (-1, "malloc()");
	return mem;
}

//用欧拉筛找出最大质数。
int
find_max_prime (int max)
{
#define MAX_SIZE max
	bool is_prime[MAX_SIZE];
	int primes[MAX_SIZE];
#undef MAX_SIZE
	memset (is_prime, true, sizeof (is_prime));
	is_prime[0] = is_prime[1] = false;
	
	int cnt = 0;
	for (int i = 2; i < max; ++i) {
		if (is_prime[i]) primes[cnt++] = i;
		for (int j = 0; j < cnt && primes[j]*i < max ; ++j) {
			is_prime[i * primes[j]] = false;
			if (i % primes[j] == 0)
				break;
		}
	}
	return primes[cnt - 1];
}

typedef struct {
	int *keys;
	size_t count;
	size_t capacity;
	int prime;
} HashTable;

HashTable *
hash_table_new (size_t size)
{
	HashTable *table = Malloc (size);
	
	*table = (HashTable) {
		.capacity = size,
		.count = 0,
		.prime = find_max_prime (size),
		.keys = Malloc (sizeof (int) * size)
	};
	
	memset (table->keys, EMPTY, sizeof (int) *size);
	return table;
}

void
hash_table_delete (HashTable *h)
{
	free (h->keys);
	free (h);
}


int
hash (const HashTable *h, int key)
{
	return key % h->prime;
}

void
hash_table_insert (HashTable *h, int key)
{
	int addr = hash (h, key);
	const int beg_addr = addr;
	for (;;) {
		if (h->keys[addr] == EMPTY) {
			h->keys[addr] = key;
			break;
		} else {
			addr = (addr + 1) % h->capacity;
			if (addr == beg_addr)
				err (-1, "hash table is full");
		}
	}
}

int
hash_table_search (const HashTable *h, int key)
{
	int addr = hash (h, key);
	const int beg_addr = addr;
	for (; h->keys[addr] != key;) {
		addr = (addr + 1) % h->capacity;
		if (h->keys[addr] == EMPTY || addr == beg_addr)
			return NOT_FOUND;
	}
	return addr;
}

void
hash_table_erase (HashTable *h, int key)
{
	int addr = hash_table_search (h, key);
	if (addr == NOT_FOUND)
		return;
	else {
		h->keys[addr] = EMPTY;
	}
}


void
hash_table_print (const HashTable *h)
{
	printf ("capacity: %ld\n", h->capacity);
	printf ("count: %ld\n", h->count);
	printf ("prime: %d\n", h->prime);
	for (int i = 0; i < h->capacity; ++i) {
		if (h->keys[i] != EMPTY) {
			printf ("\taddr: %d,\tkey: %d\n", i, h->keys[i]);
		}
	}
	
}

int
main (void)
{
	HashTable *h =  hash_table_new (100);
	hash_table_insert (h, 200);
	hash_table_insert (h, 103);
	hash_table_insert (h, 297);
	hash_table_insert (h, 38);
	hash_table_insert (h, 77);
	hash_table_insert (h, 64);
	hash_table_insert (h, 55);
	hash_table_insert (h, 21);
	hash_table_insert (h, 12);
	hash_table_print (h);
	puts ("------------------------------------");
	printf ("200\taddr: %d\n", hash_table_search (h, 200));
	printf ("103\taddr: %d\n", hash_table_search (h, 103));
	printf ("297\taddr: %d\n", hash_table_search (h, 297));
	printf ("38\taddr: %d\n", hash_table_search (h, 38));
	printf ("77\taddr: %d\n", hash_table_search (h, 77));
	printf ("64\taddr: %d\n", hash_table_search (h, 64));
	printf ("55\taddr: %d\n", hash_table_search (h, 55));
	printf ("21\taddr: %d\n", hash_table_search (h, 21));
	printf ("12\taddr: %d\n", hash_table_search (h, 12));
	puts ("------------------------------------");
	hash_table_erase (h, 200);
	hash_table_erase (h, 103);
	hash_table_erase (h, 21);
	hash_table_print (h);
	hash_table_insert (h, 200);
	puts ("------------------------------------");
	
	hash_table_print (h);
	hash_table_delete (h);
}

除留余数法 + 链地址法:

  • 待办

你可能感兴趣的:(算法,数据结构,c语言,散列表,算法)