#functions.h
#include<stdio.h>
#include<windows.h>
#include<assert.h>
typedef int KeyType; //关键字类型
typedef int ValueType;//个数类型
typedef enum type //类型
{
_EMPTY,
_EXIST,
_DELETE
}type;
typedef struct HashNode //哈希节点
{
type status;//状态
KeyType _key;//关键字数值
ValueType _value;//个数
}HashNode;
typedef struct HashTable//ha哈希表
{
HashNode* _tables;
size_t _size;//
size_t _capacity;
}HashTable;
void HashTableInit(HashTable* ht,int size)
{
assert(ht);
ht->_tables = (HashNode *)malloc(sizeof(HashNode) * size);
assert(ht->_tables);
ht->_size = 0;
ht->_capacity = size;
for (size_t i = 0;i < ht->_capacity;i++)
{
ht->_tables[i].status = _EMPTY;
}
}
void hashprint(HashTable *ht)
{
assert(ht);
assert(ht->_size > 0);
for (size_t i = 0;i < ht->_capacity;i++)
{
if (ht->_tables[i].status == _EXIST)
{
printf("%d: [key:%d value:%d]\n",i, ht->_tables[i]._key, ht->_tables[i]._value);
}
else
{
printf("%d: EMPTY\n",i);
}
}
}
int FindNextPrime(int size)
{
int i = 0;
const int _PrimeSize = 28;
static const unsigned long _PrimeList[28] =
{
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
};
for (int i = 0;i < 28;i++)
{
if (_PrimeList[i] > (unsigned long)size)
{
return _PrimeList[i];
}
}
return _PrimeList[i];
}
size_t hashfunc(HashTable *ht,KeyType key)
{
return key % (ht->_capacity);
}
void HashTableInsert(HashTable* ht, KeyType key, ValueType value)
{
//往哈希表中插入值。成功返回1,失败返回0;
//判断是否超过负载因子0.7,超过则重新申请新表,重新计算并插入所有数据。
//用开放定址法确定要插入的下标。更改数值,状态,个数。
assert(ht);
size_t load = (ht->_size) / (ht->_capacity);
if (load * 10 > 7)
{
//说明已经大于负载因子0.7,这时如果不扩容再插入哈希表,冲突的概率很大
HashTable newtable;//建新表
HashTableInit(&newtable, FindNextPrime(ht->_capacity));
for (size_t i = 0;i < ht->_capacity;i++)//重新计算哈希值并插入
{
HashTableInsert(&newtable, (ht->_tables[i])._key, (ht->_tables[i])._value);
}
free(ht->_tables);
ht->_tables = newtable._tables;
ht->_size = newtable._size;
ht->_capacity = newtable._capacity;
}
size_t index = hashfunc(ht, key);
if (ht->_tables[index].status == _EXIST && ht->_tables[index]._key == key)
{
value++;
return;
}
while (ht->_tables[index].status == _EXIST)
{
index++;
if (index == ht->_capacity)
{
index = 0;
}
}
ht->_tables[index]._key = key;
ht->_tables[index]._value = value;
ht->_tables[index].status = _EXIST;
ht->_size++;
}
HashNode* HashTableFind(HashTable* ht, KeyType key)
{
assert(ht);
size_t index = hashfunc(ht,key);
size_t flag = index;
while (ht->_tables[index].status != _EMPTY)
{
if (ht->_tables[index]._key == key)
{
return &(ht->_tables[index]);
}
if (index == ht->_capacity)
{
index = 0;
continue;
}
++index;
}
return NULL;
}
int HashTableRemove(HashTable* ht, KeyType key)
{
//在哈希表中删除关键字key
assert(ht);
size_t index = hashfunc(ht, key);
while (ht->_tables[index].status == _EXIST)
{
if (ht->_tables[index]._key == key)
{
ht->_tables[index].status = _EMPTY;
return 1;
}
if (index == ht->_capacity)
{
index = 0;
continue;
}
index++;
}
}
void HashTableDestory(HashTable* ht)
{
assert(ht);
free(ht->_tables);
ht->_tables = NULL;
ht->_size = ht->_capacity = 0;
}
#test.c
#include"functions.h"
void test()
{
HashTable ht;
HashTableInit(&ht,13);
HashTableInsert(&ht, 13, 1);
HashTableInsert(&ht, 44, 2);
HashTableInsert(&ht, 0, 1);
printf("%d\n", (ht._tables[0])._key);
printf("%d\n", HashTableFind(&ht, 0)->_key);
hashprint(&ht);
HashTableRemove(&ht, 13);
hashprint(&ht);
HashTableDestory(&ht);
}
int main()
{
test();
system("pause");
return 0;
}