哈希桶(开散列)

完整代码块

/***************************************/
//HashBucket.h

#pragma once

typedef int HBDataType;

typedef struct HashBucketNode
{
	struct HashBucketNode *_pNext;
	HBDataType _data;
}Node, *PNode;

//将data转化成整形数据
typedef int(*PDTInt)(HBDataType data);

typedef struct HashBucket
{
	PNode *_table;
	int _capacity;
	int _size;
	PDTInt _pDTInt;
}HashBucket;


void InitHashBucket(HashBucket *pHB, int capacity, PDTInt pDTInt);

int InsertHashBucket(HashBucket *pHB, HBDataType data);

int DeleteHashBucket(HashBucket *pHB, HBDataType data);

int FindHashBucket(HashBucket *pHB, HBDataType data);

int EmptyHashBucket(HashBucket *PHB);

int SizeHashBucket(HashBucket *pHB);

void DestroyHashBucket(HashBucket *pHB);

int HashFuncBucket(HashBucket *pHB, HBDataType data);

//打印哈希桶元素
void PrintHashbucket(HashBucket *pHB);



/***************************************/
//HashBucket.c
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Common.h"

void InitHashBucket(HashBucket *pHB, int capacity, PDTInt pDTInt)
{
	assert(pHB);
	capacity = GetNextPrime(capacity);
	pHB->_table = (PNode *)malloc(capacity * sizeof(PNode));
	if (NULL == pHB->_table)
	{
		assert(0);
		return;
	}

	int i = 0;
	for (i = 0; i < capacity; ++i)
		pHB->_table[i] = NULL;

	pHB->_size = 0;
	pHB->_capacity = capacity;
	pHB->_pDTInt = pDTInt;
}

PNode BuyHashBucketNode(HBDataType data)
{
	PNode pNewNode = (PNode)malloc(sizeof(Node));
	if (NULL == pNewNode)
	{
		assert(0);
		return;
	}

	pNewNode->_pNext = NULL;
	pNewNode->_data = data;

	return pNewNode;
}

//增容
void _CheckCapacity(HashBucket *pHB)
{
	assert(pHB);
	int i = 0;

	//有效元素个数与哈希桶的个数相当(最佳状态:每个桶中挂一个结点)
	if (pHB->_size == pHB->_capacity)
	{
		int newCapacity = GetNextPrime(pHB->_capacity);

		//开辟新空间
		PNode *pNewTable = (PNode *)malloc(sizeof(PNode));
		if (NULL == pNewTable)
		{
			assert(0);
			return;
		}

		pHB->_capacity = newCapacity;
		memset(pNewTable, 0, sizeof(PNode)*newCapacity);

		//拷贝元素
		for (; i < pHB->_capacity; ++i)
		{
			//将i号桶中所有结点重新哈希
			PNode pCur = pHB->_table[i];
			while (pCur)
			{
				int hashAddr = HashFuncBucket(pHB, pCur->_data);

				//将pCur从原来链表中删除
				pHB->_table[i] = pCur->_pNext;

				//将pCur插入到新链表中
				pCur->_pNext = pNewTable[hashAddr];
				pNewTable[hashAddr] = pCur;

				//取原链表中的下一个结点
				pCur = pHB->_table[i];
			}
		}

		free(pHB->_table);
		pHB->_table = pNewTable;
	}
}

int InsertHashBucket(HashBucket *pHB, HBDataType data)
{
	assert(pHB);
	int bucketNo;
	PNode pCur = NULL;

	_CheckCapacity(pHB);

	//计算哈希桶号
	bucketNo = HashFuncBucket(pHB, data);

	//检测元素是否在哈希表中
	while (pCur)
	{
		if (data == pCur->_data)
			return 0;

		pCur = pCur->_pNext;
	}

	//插入元素--->头插法
	pCur = BuyHashBucketNode(data);
	pCur->_pNext = pHB->_table[bucketNo];
	pHB->_table[bucketNo] = pCur;
	pHB->_size++;
	return 1;

}

int DeleteHashBucket(HashBucket *pHB, HBDataType data)
{
	assert(pHB);
	int bucketNo;
	PNode pCur = NULL;
	PNode pParent = NULL;

	bucketNo = HashFuncBucket(pHB, data);
	pCur = pHB->_table[bucketNo];
	while (pCur)
	{
		if (data == pCur->_data)
		{
			//删除第一个结点
			if (pCur = pHB->_table[bucketNo])
			{
				pHB->_table[bucketNo] = pCur->_pNext;
				free(pCur);
			}
			else
				pParent->_pNext = pCur->_pNext;

			free(pCur);
			pHB->_size--;
			return 1;
		}

		pParent = pCur;
		pCur = pCur->_pNext;
	}
}

int FindHashBucket(HashBucket *pHB, HBDataType data)
{
	assert(pHB);
	int bucketNo;
	PNode pCur = NULL;

	bucketNo = HashFuncBucket(pHB, data);
	pCur = pHB->_table[bucketNo];
	while (pCur)
	{
		if (data == pCur->_data)
			return 1;

		pCur = pCur->_pNext;
	}

	return 0;
}

int EmptyHashBucket(HashBucket *pHB)
{
	assert(pHB);
	return 0 == pHB->_size;
}

int SizeHashBucket(HashBucket *pHB)
{
	return pHB->_size;
}

void DestroyHashBucket(HashBucket *pHB)
{
	assert(pHB);
	int i = 0;
	for (; i < pHB->_capacity; ++i)
	{
		PNode pDel = pHB->_table[i];
		while (pDel)
		{
			pHB->_table[i] = pDel->_pNext;
			free(pDel);
			pDel = pHB->_table[i];
		}
	}

	free(pHB->_table);
	pHB->_table = NULL;
	pHB->_capacity = 0;
	pHB->_size = 0;
}

int HashFuncBucket(HashBucket *pHB, HBDataType data)
{
	assert(pHB);
	return pHB->_pDTInt(data) % pHB->_capacity;
}

//打印哈希桶元素
void PrintHashbucket(HashBucket *pHB)
{
	assert(pHB);
	int i = 0;
	for (; i < pHB->_capacity; ++i)
	{
		PNode pCur = pHB->_table[i];
		printf("table[%d]:", i);
		while (pCur)
		{
			printf("%d-->", pCur->_data);
			pCur = pCur->_pNext;
		}

		printf("NULL\n");
	}
}



/***************************************/
//Common.h

#pragma once

//素数表
unsigned long GetNextPrime(unsigned long prime);

//字符串类型
unsigned long StrToINT(const char * str);

//默认转化方法
unsigned long DefToINT(long data);


/////////////////////////////////////////////////
//Common.c
#define PRIME_SIZE 28

//素数表
unsigned long GetNextPrime(unsigned long prime)
{

	// 使用素数表对齐做哈希表的容量,降低哈希冲突      
	static const unsigned long _PrimeList [PRIME_SIZE] =     
	{         
		53ul,         97ul,         193ul,       389ul,       769ul,         
		1543ul,       3079ul,       6151ul,      12289ul,     24593ul,         
		49157ul,      98317ul,      196613ul,    393241ul,    786433ul,         
		1572869ul,    3145739ul,    6291469ul,   12582917ul,  25165843ul,         
		50331653ul,   100663319ul,  201326611ul, 402653189ul, 805306457ul,         
		1610612741ul, 3221225473ul, 4294967291ul     
	}; 

	int i = 0;
	for (i = 0; i < PRIME_SIZE; ++i)
	{
		if (_PrimeList[i] > prime)
			return _PrimeList[i];
	}

	return _PrimeList[PRIME_SIZE - 1];
}

//字符串类型
unsigned long StrToINT(const char * str)
{
	unsigned int seed = 131; // 31 131 1313 13131 131313
	unsigned int hash = 0;      
	while (*str)     
	{ 
		hash = hash * seed + (*str++); 
	}      
	return (hash & 0x7FFFFFFF);
}

//默认转化方法
unsigned long DefToINT(long data)
{
	return data;
}



/***************************************/
//test.c
#include "HashBucket.h"

void TestHashBucket()
{
	HashBucket ht;
	InitHashBucket(&ht, 10, DefToINT);
	InsertHashBucket(&ht, 11);
	InsertHashBucket(&ht, 6);
	InsertHashBucket(&ht, 49);
	InsertHashBucket(&ht, 28);
	InsertHashBucket(&ht, 10);
	InsertHashBucket(&ht, 23);
	InsertHashBucket(&ht, 14);
	InsertHashBucket(&ht, 35);
	InsertHashBucket(&ht, 22);
	InsertHashBucket(&ht, 27);
	InsertHashBucket(&ht, 17);
	InsertHashBucket(&ht, 17);
		
	printf("size = %d\n", SizeHashBucket(&ht));
	PrintHashbucket(&ht);
	DestroyHashBucket(&ht);
}

int main()
{
	TestHashBucket();
	system("pause");
	return 0;
}

结果输出:
哈希桶(开散列)