Common.h
#pragma once
unsigned long GetNextPrime(unsigned long num);
Common.c
#include "Common.h"
#define _PrimeSize 28
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 GetNextPrime(unsigned long num)
{
int i = 0;
for (; i < _PrimeSize; ++i)
{
if (num <= _PrimeList[i])
return _PrimeList[i];
}
return _PrimeList[_PrimeSize - 1];
}
HashBucket.h
#pragma once
#include
#include
#include
#include
#include
typedef int K;
typedef int V;
typedef struct Pair
{
K _key;
V _value;
}Pair;
typedef struct HashNode
{
struct HashNode *_pNext;
Pair _data;
}HashNode, *Node;
typedef struct HashTable
{
Node* table;
unsigned long _capacity;
size_t _size;
}HT;
void InitHashBucket(HT *ht, int capacity);
int HashFun(HT *ht, K key);
Node BuyNode(K key, V value);
void checkCapacity(HT *ht);
int InsertHashBucketUnique(HT * ht, K key, V v);
void InsertHashBucketEqual(HT * ht, K key, V v);
int DeleteUnique(HT *ht, K key);
int DeleteEqual(HT *ht, K key);
Node FindHashBucket(HT* ht, K key);
void PrintHashBucket(HT* ht);
void DestroyHashBucket(HT* ht);
HashBucket.c
#include "HashBucket.h"
#include "Common.h"
void InitHashBucket(HT *ht, int capacity)
{
int i = 0;
capacity = GetNextPrime(capacity);
ht->table = (Node*)malloc(sizeof(Node)*capacity);
if (NULL == ht->table)
{
return;
}
for (; i < capacity; ++i)
{
ht->table[i] = NULL;
}
ht->_size = 0;
ht->_capacity = capacity;
}
Node BuyNode(K key, V value)
{
Node pnewnode = (Node)malloc(sizeof(HashNode));
assert(pnewnode);
pnewnode->_pNext = NULL;
pnewnode->_data._key = key;
pnewnode->_data._value = value;
return pnewnode;
}
int HashFun(HT *ht, K key)
{
return key % ht->_capacity;
}
void checkCapacity(HT *ht)
{
assert(ht);
unsigned long BucketIdx = 0;
Node pcur = NULL;
if (ht->_size == ht->_capacity)
{
unsigned long newcapacity = GetNextPrime(ht->_capacity);
Node *newtable = (Node*)malloc(sizeof(Node)*newcapacity);
assert(newtable);
for (; BucketIdx < ht->_capacity; ++BucketIdx)
{
pcur = ht->table[BucketIdx];
while (pcur)
{
int BucketNO = pcur->_data._key % newcapacity;
ht->table[BucketIdx] = pcur->_pNext;
pcur->_pNext = newtable[BucketNO];
newtable[BucketNO] = pcur;
pcur = ht->table[BucketIdx];
}
}
free(ht->table);
ht->table = newtable;
}
}
int InsertHashBucketUnique(HT * ht, K key, V v)
{
assert(ht);
checkCapacity(ht);
int bucketNO = HashFun(ht, key);
Node pcur = ht->table[bucketNO];
while (pcur)
{
if (pcur->_data._key == key)
return 0;
pcur = pcur->_pNext;
}
Node pnewnode = BuyNode(key, v);
pnewnode->_pNext = ht->table[bucketNO];
ht->table[bucketNO] = pnewnode;
ht->_size++;
return 1;
}
void InsertHashBucketEqual(HT * ht, K key, V v)
{
assert(ht);
checkCapacity(ht);
int bucketNO = HashFun(ht, key);
Node pnewnode = BuyNode(key, v);
pnewnode->_pNext = ht->table[bucketNO];
ht->table[bucketNO] = pnewnode;
ht->_size++;
}
Node FindHashBucket(HT* ht, K key)
{
assert(ht);
int bucketNO = HashFun(ht, key);
Node pcur = ht->table[bucketNO];
while (pcur)
{
if (pcur->_data._key == key)
return pcur;
pcur = pcur->_pNext;
}
return NULL;
}
int DeleteUnique(HT *ht, K key)
{
assert(ht);
int BucketNo = HashFun(ht, key);
int oldsize = ht->_size;
Node pPre = NULL;
Node pcur = NULL;
pcur = ht->table[BucketNo];
while (pcur)
{
if (pcur->_data._key == key)
{
if (pcur == ht->table[BucketNo])
{
ht->table[BucketNo] = pcur->_pNext;
free(pcur);
return 1;
}
else
{
pPre = pcur;
pcur = pcur->_pNext;
pPre->_pNext = pcur->_pNext;
free(pcur);
return 1;
}
}
}
return 0;
}
int DeleteEqual(HT *ht, K key)
{
assert(ht);
assert(ht);
int BucketNo = HashFun(ht, key);
int oldsize = ht->_size;
Node pPre = NULL;
Node pcur = NULL;
pcur = ht->table[BucketNo];
while (pcur)
{
if (pcur->_data._key == key)
{
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;
}
}
return oldsize != ht->_size;
}
void DestroyHashBucket(HT* ht)
{
assert(ht);
unsigned long i = 0;
for (; i < ht->_capacity; ++i)
{
Node pcur = ht->table[i];
while (pcur)
{
ht->table[i]= pcur->_pNext;
free(pcur);
pcur = ht->table[i];
}
}
free(ht->table);
ht->table = NULL;
ht->_size = 0;
ht->_capacity = 0;
}
void PrintHashBucket(HT* ht)
{
assert(ht);
unsigned int BucketIdx = 0;
for (; BucketIdx < ht->_capacity; ++BucketIdx)
{
Node pcur = ht->table[BucketIdx];
printf("%lu \n", BucketIdx);
while (pcur)
{
printf(" \n", pcur->_data._key, pcur->_data._value);
pcur = pcur->_pNext;
}
}
}
void test()
{
HT ht;
InitHashBucket(&ht, 10);
Node pcur = NULL;
InsertHashBucketEqual(&ht, 5, 1);
InsertHashBucketEqual(&ht, 9, 2);
InsertHashBucketEqual(&ht, 25, 3);
InsertHashBucketEqual(&ht, 35, 4);
InsertHashBucketEqual(&ht, 62, 4);
DeleteUnique(&ht, 35);
pcur = FindHashBucket(&ht, 25);
PrintHashBucket(&ht);
printf("\n");
printf("key = %d , v = %d ", pcur->_data._key, pcur->_data._value);
DestroyHashBucket(&ht);
}
test.c
void main()
{
test();
system("pause");
}