头文件
- HashBucket.h
#pragma once
#ifndef _HASHBUCKET_H_
#define _HASHBUCKET_H_
#define size_t unsigned long
typedef int K;
//typedef char* K;
typedef char* V;
typedef size_t(*PHF)(K key);
typedef struct Pair
{
K _key;
V _value;
}Pair;
typedef struct Node
{
struct Node* _pNext;
Pair _data;
}Node, *PNode;
typedef struct HashTable
{
PNode* _table;
unsigned long _capacity;
unsigned long _size;
PHF _DateToInt;
}HT;
void InitHashBucket(HT* ht, int capacity, PHF dataToInt);
int InsertHashBucketUnique(HT* ht, K key, V v);
int DeleteHashBucketUnique(HT* ht, K key);
void InsertHashBucketEqual(HT* ht, K key, V v);
int DeleteHashBucketEqual(HT* ht, K key);
PNode FindHashBucket(HT* ht, K key);
int ChechCapacity(HT* ht);
void DestroyHashBucket(HT* ht);
void ExtendCapacity(HT* ht);
int HashFunc(HT* ht, K key);
PNode BuyNode(K key, V value);
void PrintHashBucket(HT* ht);
#endif // !_HASHBUCKET_H_
- common.h
#pragma once
#ifndef _COMMON_H_
#define _COMMON_H_
#include"HashBucket.h"
#pragma once
#define _PrimeSize 28
#define size_t unsigned long
static const unsigned long _PrimeList[_PrimeSize] =
{
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
};
unsigned long GetPrimeNumber(int Capacity);
static size_t BKDRHash(const char * str);
size_t IntToInt(K key);
size_t StrToInt(K key);
#endif // !_COMMON_H_
源文件
- HashBucket.c
#include<stdio.h>
#include<assert.h>
#include"HashBucket.h"
#include"common.h"
#pragma warning(disable:4996);
//初始化
void InitHashBucket(HT* ht, int capacity, PHF dataToInt)
{
assert(ht);
ht->_capacity = capacity;
ht->_DateToInt = dataToInt;
ht->_size = 0;
ht->_table = (PNode*)malloc(sizeof(PNode) * ht->_capacity);
for (int i = 0; i < ht->_capacity; i++)
{
ht->_table[i] = NULL;
}
}
//插入唯一
int InsertHashBucketUnique(HT* ht, K key, V v)
{
assert(ht);
if (ChechCapacity(ht))
{
ExtendCapacity(ht);
}
size_t BucketNo = HashFunc(ht, key);
PNode pCur = ht->_table[BucketNo];
while (pCur)
{
if (pCur->_data._key == key)
return 0;
else
pCur = pCur->_pNext;
}
pCur = BuyNode(key, v);
pCur->_pNext = ht->_table[BucketNo];
ht->_table[BucketNo] = pCur;
ht->_size++;
return 1;
}
//删除唯一
int DeleteHashBucketUnique(HT* ht, K key)
{
assert(ht);
size_t BucketNo = HashFunc(ht, key);
PNode pCur = ht->_table[BucketNo];
PNode pPre = ht->_table[BucketNo];
if (ht->_table[BucketNo] && ht->_table[BucketNo]->_data._key == key)
{
ht->_table[BucketNo]= pCur->_pNext;
ht->_size--;
free(pCur);
return 1;
}
pCur = ht->_table[BucketNo]->_pNext;
pPre = ht->_table[BucketNo];
while (pCur)
{
if (pCur->_data._key == key)
break;
else
{
pPre = pCur;
pCur = pCur->_pNext;
}
}
if (NULL == pCur)
return 0;
pPre->_pNext = pCur->_pNext;
free(pCur);
ht->_size--;
return 1;
}
//插入相同的
void InsertHashBucketEqual(HT* ht, K key, V v)
{
assert(ht);
if (ChechCapacity(ht))
{
ExtendCapacity(ht);
}
size_t BucketNo = HashFunc(ht, key);
PNode pCur = BuyNode(key, v);
pCur->_pNext = ht->_table[BucketNo];
ht->_table[BucketNo] = pCur;
ht->_size++;
}
//删除相同的
int DeleteHashBucketEqual(HT* ht, K key)
{
assert(ht);
int flag = ht->_size;
size_t BucketNo = HashFunc(ht, key);
PNode pCur = ht->_table[BucketNo];
PNode pPre = ht->_table[BucketNo];
while(ht->_table[BucketNo] && ht->_table[BucketNo]->_data._key == key)
{
ht->_table[BucketNo] = pCur->_pNext;
ht->_size--;
free(pCur);
pCur = ht->_table[BucketNo];
}
if (pCur)
pCur = ht->_table[BucketNo]->_pNext;
while (pCur)
{
if (pCur->_data._key == key)
{
pPre->_pNext = pCur->_pNext;
free(pCur);
pCur = pPre->_pNext;
ht->_size--;
}
else
{
pPre = pCur;
pCur = pCur->_pNext;
}
}
return flag != ht->_size ;
}
//搜索
PNode FindHashBucket(HT* ht, K key)
{
assert(ht);
int flag = ht->_size;
size_t BucketNo = HashFunc(ht, key);
PNode pCur = ht->_table[BucketNo];
while (pCur)
{
if (pCur->_data._key == key)
{
break;
}
else
{
pCur = pCur->_pNext;
}
}
return pCur;
}
//检查空间
int ChechCapacity(HT* ht)
{
return ht->_capacity == ht->_size;
}
//销毁哈希桶
void DestroyHashBucket(HT* ht)
{
assert(ht);
PNode pDel;
int BucketInd = 0;
for (; BucketInd < ht->_capacity; BucketInd++)
{
pDel = ht->_table[BucketInd];
while (pDel)
{
ht->_table[BucketInd] = pDel->_pNext;
free(pDel);
pDel = ht->_table[BucketInd];
}
}
free(ht->_table);
ht->_size = 0;
ht->_capacity = 0;
}
//哈希函数
int HashFunc(HT* ht, K key)
{
assert(ht);
return ht->_DateToInt(key) % ht->_capacity;
}
//创建结点
PNode BuyNode(K key, V value)
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
pNewNode->_data._key = key;
pNewNode->_data._value = value;
pNewNode->_pNext = NULL;
return pNewNode;
}
//打印
void PrintHashBucket(HT* ht)
{
assert(ht);
PNode pCur;
int BucketInd = 0;
for (; BucketInd < ht->_capacity; BucketInd++)
{
printf("Hash Bucket No.%ld:", BucketInd);
pCur = ht->_table[BucketInd];
while (pCur)
{
printf("<%s, %s>\t", pCur->_data._key, pCur->_data._value);
pCur = pCur->_pNext;
}
printf("\n");
}
}
//打印
void PrintHashBucket_int(HT* ht)
{
assert(ht);
PNode pCur;
int BucketInd = 0;
for (; BucketInd < ht->_capacity; BucketInd++)
{
printf("Hash Bucket No.%ld:", BucketInd);
pCur = ht->_table[BucketInd];
while (pCur)
{
printf("<%d, %s>\t", pCur->_data._key, pCur->_data._value);
pCur = pCur->_pNext;
}
printf("\n");
}
}
//扩容
void ExtendCapacity(HT* ht)
{
size_t NewCapacity = ht->_capacity + 5;
PNode* pNewNode = (PNode*)malloc(sizeof(PNode) * NewCapacity);//申请新的空间
for (int i = 0; i < NewCapacity; i++)
{
pNewNode[i] = NULL;
}
PNode pCur;
size_t BucketInd = 0;
for (; BucketInd < ht->_capacity; BucketInd++)//开始交换结点
{
if (ht->_table[BucketInd])
{
size_t BucketNo = 0;
pCur = ht->_table[BucketInd];
while (pCur)
{
//BucketNo = HashFunc(ht, pCur->_data._key);
BucketNo = ht->_DateToInt(pCur->_data._key) % NewCapacity;
ht->_table[BucketInd] = pCur->_pNext;
pCur->_pNext = pNewNode[BucketNo];
pNewNode[BucketNo] = pCur;
pCur = ht->_table[BucketInd];
}
}
}
free(ht->_table);
ht->_table = pNewNode;
ht->_capacity = NewCapacity;
}
/////////////////////////////////////////////////-----测试
void test_str()
{
HT ht;
InitHashBucket(&ht, 5, StrToInt);
InsertHashBucketUnique(&ht, "ac", "鹌鹑");
InsertHashBucketUnique(&ht, "rg", "如果");
InsertHashBucketUnique(&ht, "lm", "里面");
InsertHashBucketUnique(&ht, "et", "儿童");
InsertHashBucketUnique(&ht, "ht", "合同");
PrintHashBucket(&ht);
printf("---------------------------------------\n");
InsertHashBucketUnique(&ht, "pn", "陪你");
InsertHashBucketUnique(&ht, "yn", "一年");
InsertHashBucketUnique(&ht, "qn", "去年");
InsertHashBucketUnique(&ht, "ynddd", "一年d");
InsertHashBucketUnique(&ht, "qnqqd", "去年qdq");
PrintHashBucket(&ht);
printf("---------------------------------------\n");
InsertHashBucketUnique(&ht, "asdpn", "驴妈陪你");
InsertHashBucketUnique(&ht, "asdyn", "的一年");
InsertHashBucketUnique(&ht, "aedsdqn", "大去年");
InsertHashBucketUnique(&ht, "fegynddd", "就看到一年d");
InsertHashBucketUnique(&ht, "gefqnqqd", "按时去年qdq");
PrintHashBucket(&ht);
printf("---------------------------------------\n");
}
void FindTest(HT* ht, size_t key)
{
PNode pNew = FindHashBucket(ht, key);
printf("key = %ld: ", key);
if (pNew)
{
printf("<%ld,%s>\n", pNew->_data._key, pNew->_data._value);
}
printf("\n");
}
void test_int()
{
HT ht;
InitHashBucket(&ht, 5, IntToInt);
//插入,扩容测试
InsertHashBucketUnique(&ht, 1, "鹌鹑");//1
InsertHashBucketUnique(&ht, 4, "如果");//4
InsertHashBucketUnique(&ht, 13, "里面");//3
InsertHashBucketUnique(&ht, 25, "儿童");//0
InsertHashBucketUnique(&ht, 103, "合同");//3
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
InsertHashBucketUnique(&ht, 32, "陪你");//2
InsertHashBucketUnique(&ht, 19, "一年");//9
InsertHashBucketUnique(&ht, 67, "去年");//7
InsertHashBucketUnique(&ht, 28, "一年d");//8
InsertHashBucketUnique(&ht, 97, "去年qdq");//7
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
InsertHashBucketUnique(&ht, 15, "驴妈陪你");//0
InsertHashBucketUnique(&ht, 94, "的一年");//4
InsertHashBucketUnique(&ht, 252, "大去年");//10
InsertHashBucketUnique(&ht, 29, "就看到一年d");//14
InsertHashBucketUnique(&ht, 27, "按时去年qdq");//13
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
InsertHashBucketUnique(&ht, 27, "按时去年qdq");//13
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
DeleteHashBucketUnique(&ht, 15);
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
InsertHashBucketEqual(&ht, 27, "aaaaaaaa");
InsertHashBucketEqual(&ht, 27, "aaaaaaaa");
InsertHashBucketEqual(&ht, 27, "aaaaaaaa");
InsertHashBucketEqual(&ht, 27, "aaaaaaaa");
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
DeleteHashBucketEqual(&ht, 27);
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
size_t k = 1;
while ( k)
{
scanf("%ld",&k);
FindTest(&ht, k);
}
DestroyHashBucket(&ht);
PrintHashBucket_int(&ht);
printf("---------------------------------------\n");
}
int main()
{
//test_str();
test_int();
system("pause");
return 0;
}
- common.c
#include"common.h"
size_t GetPrimeNumber(int Capacity)//得到最接近的质数
{
for (int i = 0; i < _PrimeSize; i++)
{
if (_PrimeList[i] > Capacity)
return _PrimeList[i];
}
return _PrimeList[_PrimeSize];
}
static size_t BKDRHash(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);
}
size_t IntToInt(K key)
{
return key;
}
size_t StrToInt(K key)
{
return BKDRHash(key);
}