链地址法及其模拟实现

什么是哈希表

哈希表也称为散列表,强调的是一种映射关系,指的是关键值与存储位置的映射关系

我们常说在建立哈希表的时候,不仅要选择一个好的哈希函数,而且要设定一种处理冲突的方法

哈希函数减少冲突的方法有开放定址法,再哈希法,链地址法,建立公共溢出区

其中最常用减少冲突的方法为链地址法,如图(例)

 链地址法及其模拟实现_第1张图片

 模拟实现(例下)

#include 
#ifndef _HASH_H_
#define _HASH_H_

#include 
#include 
#include 
#define HashElemType int
#define P 7

typedef struct HashNode
{
	HashElemType data;
	struct HashNode* next;
}HashNode;

typedef struct HashTable   //表里面元素是链表类型
{
	HashNode* *htable;
}HashTable;

void HashTableInit(HashTable* pht);                 //初始化
void HashTableDestroy(HashTable* pht);              //摧毁
void HashTableInsert(HashTable* pht, HashElemType v);  //插入元素
void HashTableRemove(HashTable* pht, HashElemType key); //移除元素 
HashNode* HashTableFind(HashTable* pht, HashElemType key); //查找元素
void HashTableClear(HashTable* pht);                      //清空哈希表
size_t HashTableSize(HashTable* pht);                  //求哈希表长度 
void HashTableShow(HashTable* pht);                    //展示哈希表


int Hash(HashElemType key)
{
	//除留余数法
	return key % P;
}

void HashTableInit(HashTable* pht)
{
	pht->htable = (HashNode**)malloc(sizeof(HashNode*) * P);
	assert(pht->htable != NULL);
	memset(pht->htable, 0, sizeof(HashNode) * P);
}

void HashTableDestroy(HashTable* pht)
{
	HashTableClear(pht);
	free(pht->htable);
	pht->htable = NULL;
}


void HashTableInsert(HashTable* pht, HashElemType v)
{
	assert(pht != NULL);
	//1、index
	int index = Hash(v);

	//2、申请节点进行插入
	HashNode* s = (HashNode*)malloc(sizeof(HashNode));
	s->data = v;
	s->next = pht->htable[index];
	pht->htable[index] = s;
}

void HashTableRemove(HashTable* pht, HashElemType key)
{
	assert(pht != NULL);
	int index = Hash(key);
	HashNode* p = pht->htable[index];
	if (p == NULL)
		return;

	if (p->data == key)   //存在且是第一个节点
		pht->htable[index] = p->next;
	else
	{
		HashNode* pre;
		while (p->next != NULL && p->next->data != key)
			p = p->next;
		if (p->next == NULL)
			return;
		pre = p;
		p = p->next;
		pre->next = p->next;
	}
	free(p);
}

HashNode* HashTableFind(HashTable* pht, HashElemType key)
{
	assert(pht != NULL);
	int index = Hash(key);
	HashNode* p = pht->htable[index];
	while (p != NULL && p->data != key)
		p = p->next;
	return p;
}

void HashTableShow(HashTable* pht)
{
	for (int i = 0; i < P; ++i)
	{
		printf("%d : ", i);
		HashNode* p = pht->htable[i];
		while (p != NULL)
		{
			printf("%d-->", p->data);
			p = p->next;
		}
		printf("NULL.\n");
	}
}

void HashTableClear(HashTable* pht)
{
	assert(pht != NULL);
	for (int i = 0; i < P; ++i)
	{
		HashNode* p = pht->htable[i];
		while (p != NULL)
		{
			pht->htable[i] = p->next;
			free(p);

			p = pht->htable[i];
		}
	}
}

size_t HashTableSize(HashTable* pht)
{
	assert(pht != NULL);
	size_t count = 0;
	for (int i = 0; i < P; ++i)
	{
		HashNode* p = pht->htable[i];
		while (p != NULL)
		{
			count++;
			p = p->next;
		}
	}

	return count;
}

#endif

你可能感兴趣的:(数据结构,哈希表,链地址法)