下面为开散列表的代码实现:
闭散列表代码实现参考:https://blog.csdn.net/virgofarm/article/details/80396215
HashBucket.h
#ifndef __HASHBUCKET_H__
#define __HASHBUCKET_H__
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
typedef int DataType;
typedef size_t(*PDTInt)(DataType str);
//哈希桶的每个节点类型
typedef struct HashBucketNode
{
DataType _data;
struct HashBucketNode* _pNext;
}HBN;
//哈希桶类型
typedef struct HushBucket
{
HBN** _table; //哈希桶空间--放的是节点的地址,所以是二级指针
int _capacity; //空间容量
int _size; //共有多少个有效元素--总节点个数
PDTInt pDTInt; //将数据类型转化为整形,因为哈希函数除留余数法
}HBucket;
//初始化
void HashBucketInit(HBucket* ht, int capacity, PDTInt pDTInt);
//创建哈希桶节点
HBN* BuyHushBucketNode(DataType data);
//插入元素 -- data唯一
void HashBucketInsertUnique(HBucket* ht, DataType data);
//删除元素--data唯一
void HashBucketDeleteUnique(HBucket* ht, DataType data);
//插入元素--data不唯一
void HashBucketInsertEqual(HBucket* ht, DataType data);
//删除所有值为data的节点
void HashBucketDeleteEqual(HBucket* ht, DataType data);
//哈希桶中共有多少个节点
int HashBucketSize(HBucket* ht);
//判空
int HashBucketEmpty(HBucket* ht);
//哈希桶中共有多少个桶
int HashBucketCount(HBucket* ht);
//在桶号为BucketNO的桶中有多少个节点
int HashBucketBucketSize(HBucket* ht, int BucketNo);
//打印哈希桶
void PrintHashBucket(HBucket* ht);
//销毁哈希桶
void HashBucketDestroy(HBucket* ht);
#endif
HashBucket.c
#include "HashBucket.h"
#include "comm.h"
//哈希函数
static int HashFunc(HBucket* ht, int data)
{
assert(ht);
return ht->pDTInt(data) % (ht->_capacity);
}
//初始化
void HashBucketInit(HBucket* ht, int capacity, PDTInt pDTInt)
{
assert(ht);
capacity = GetCapacity(capacity);
//calloc有初始化,将每个指针初始化为NULL
ht->_table = (HBN**)calloc(capacity, sizeof(HBN*));
if (NULL == ht->_table)
{
assert(0);
return;
}
ht->_size = 0;
ht->_capacity = capacity;
ht->pDTInt = pDTInt;
}
//创建哈希桶节点
HBN* BuyHushBucketNode(DataType data)
{
HBN* pNewNode = NULL;
pNewNode = (HBN*)malloc(sizeof(HBN));
if (pNewNode == NULL)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
//插入元素 -- data唯一
void HashBucketInsertUnique(HBucket* ht, DataType data)
{
int BucketNo = -1;
HBN* pCur = NULL;
assert(ht);
BucketNo = HashFunc(ht, data);//用哈希函数算出插入数据的桶号
//先判断桶号所指的链表中是否已经存在data
pCur = ht->_table[BucketNo];
while (pCur)
{
//如果已经存在就返回
if (pCur->_data == data)
return;
pCur = pCur->_pNext;
}
//不存在直接头插
pCur = BuyHushBucketNode(data); //创建新节点
pCur->_pNext = ht->_table[BucketNo];
ht->_table[BucketNo] = pCur;
ht->_size++;
}
//删除元素--data唯一
void HashBucketDeleteUnique(HBucket* ht, DataType data)
{
int BucketNo = -1;
HBN* pCur = NULL;
HBN* pPre = NULL;
assert(ht);
BucketNo = HashFunc(ht, data);//用哈希函数算出插入数据的桶号
//找到data
pCur = ht->_table[BucketNo];
while (pCur)
{
if (pCur->_data == data)
{
//为第一个个节点
if (pCur == ht->_table[BucketNo])
ht->_table[BucketNo] = pCur->_pNext;
else
pPre->_pNext = pCur->_pNext;
free(pCur);
ht->_size--;
return;
}
else
{
pPre = pCur;
pCur = pCur->_pNext;
}
}
}
//插入元素--data不唯一
void HashBucketInsertEqual(HBucket* ht, DataType data)
{
int BucketNo = -1;
HBN* pCur = NULL;
assert(ht);
BucketNo = HashFunc(ht, data);
//直接头插
pCur = BuyHushBucketNode(data);
pCur->_pNext = ht->_table[BucketNo];
ht->_table[BucketNo] = pCur;
ht->_size++;
}
//删除所有值为data的节点
void HashBucketDeleteEqual(HBucket* ht, DataType data)
{
int BucketNo = -1;
HBN* pCur = NULL;
HBN* pPre = NULL;
assert(ht);
BucketNo = HashFunc(ht, data);
pCur = ht->_table[BucketNo];
while (pCur)
{
if (pCur->_data == data)
{
//第一个节点
if (pCur == ht->_table[BucketNo])
{
ht->_table[BucketNo] = pCur->_pNext;
free(pCur);
//从头开始继续找
pCur = ht->_table[BucketNo];
}
else
{
pPre->_pNext = pCur->_pNext;
free(pCur);
//从下个节点继续找
pCur = pPre->_pNext;
}
ht->_size--;
}
else
{
pPre = pCur;
pCur = pCur->_pNext;
}
}
}
//哈希桶中共有多少个节点
int HashBucketSize(HBucket* ht)
{
assert(ht);
return ht->_size;
}
//判空
int HashBucketEmpty(HBucket* ht)
{
assert(ht);
return 0 == ht->_size;
}
//哈希桶中共有多少个桶
int HashBucketCount(HBucket* ht)
{
assert(ht);
return ht->_capacity;
}
//在桶号为BucketNO的桶中有多少个节点
int HashBucketBucketSize(HBucket* ht, int BucketNo)
{
int count = 0;
HBN* pCur = NULL;
assert(ht);
pCur = ht->_table[BucketNo];
while (pCur)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
//销毁哈希桶
void HashBucketDestroy(HBucket* ht)
{
int i = 0;
HBN* pCur;
assert(ht);
for (; i < ht->_capacity; i++)
{
pCur = ht->_table[i];
while (pCur)
{
ht->_table[i] = pCur->_pNext;
free(pCur);
pCur = ht->_table[i];
}
}
ht->_capacity = 0;
ht->_size = 0;
free(ht->_table);
ht->_table = NULL;
}
//打印哈希桶
void PrintHashBucket(HBucket* ht)
{
assert(ht);
int i = 0;
for (; i < ht->_capacity; i++)
{
HBN* pCur = ht->_table[i];
printf("HashTable[%d]:", i);
while (pCur)
{
printf("%d-->", pCur->_data);
pCur = pCur->_pNext;
}
printf("\n");
}
}
test.c
include “comm.h”
include “HashBucket.h”
void TestHashBucket()
{
HBucket ht;
HashBucketInit(&ht, 10, IntToInt);
HashBucketInsertUnique(&ht, 2);//插入元素,data唯一
HashBucketInsertUnique(&ht, 4);
HashBucketInsertUnique(&ht, 6);
HashBucketInsertUnique(&ht, 12);
HashBucketDeleteUnique(&ht, 6);//删除data
printf("HashBucketSize:%d\n", HashBucketSize(&ht));
printf("HashBucketCount:%d\n", HashBucketCount(&ht));
printf("HashBucketBucketSize:%d\n", HashBucketBucketSize(&ht, 2));
HashBucketInsertEqual(&ht, 2);//插入元素,data不唯一
printf("HashBucketSize:%d\n", HashBucketSize(&ht));
printf("HashBucketCount:%d\n", HashBucketCount(&ht));
printf("HashBucketBucketSize:%d\n", HashBucketBucketSize(&ht, 2));
HashBucketDeleteEqual(&ht, 2);//删除所有值为data的元素
printf("HashBucketBucketSize:%d\n", HashBucketBucketSize(&ht, 2));
HashBucketDestroy(&ht);
}
int main()
{
//TestHashTable();//动态闭散列哈希表
TestHashBucket();//开散列哈希桶
}