//enmu枚举在.c格式的代码中可能不兼容,建议用.cpp去运行
#include<malloc.h>
#include<assert.h>
typedef int KeyType;
typedef int ValueType;
enum Status
{
EMPTY,
EXITS,
DELETE,
};
typedef struct HashNode
{
KeyType _key;
ValueType _value;
Status _status;
}HashNode;
typedef struct HashTable
{
HashNode* _tables;
size_t _size;
size_t _N;
}HashTable;
size_t Get_Next_Prime_Num(size_t cur_num); //素数表
size_t HashFunc(HashTable* ht, KeyType key); //哈希函数位置分配
void check_Capacity(HashTable* ht); //检查容量
void HashTableInit(HashTable* ht); //创建哈希表
void HashTableInsert(HashTable* ht, KeyType key, ValueType value); //插入
HashNode* HashTableFind(HashTable* ht, KeyType key); //查找
int HashTableRemove(HashTable* ht, KeyType key); //删除
void HashTableDestory(HashTable* ht);//销毁表
void check_Capacity(HashTable* ht)
{
if (ht->_size * 10 / ht->_N >= 7)
{
HashTable newht;
newht._N = ht->_N;
HashTableInit(&newht);
for (size_t i = 0; i < ht->_N; i++)
{
if (ht->_tables[i]._status == EXITS)
{
HashTableInsert(&newht, ht->_tables[i]._key,ht->_tables[i]._value);
}
HashTableDestory(ht);
ht->_tables = newht._tables;
ht->_size = newht._size;
ht->_N = newht._N;
}
}
}
size_t Get_Next_Prime_Num(size_t cur_num)//素数表
{
const int _PrimeSize = 28;
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
};
for (size_t i = 0; i < _PrimeSize; i++)
{
if (cur_num < _PrimeList[i])
{
return _PrimeList[i];
}
}
return _PrimeList[_PrimeSize - 1];
}
size_t HashFunc(HashTable* ht, KeyType key)
{
return key % ht->_N;
}
void HashTableInit(HashTable* ht)
{
ht->_tables = (HashNode*)malloc(sizeof(HashNode) * Get_Next_Prime_Num(0));
assert(ht->_tables);
ht->_size = 0;
ht->_N = Get_Next_Prime_Num(0);
for (size_t i = 0; i < ht->_N; i++)
{
ht->_tables[i]._status = EMPTY;
}
}
void HashTableInsert(HashTable* ht, KeyType key, ValueType value)
{
check_Capacity(ht);
size_t index = HashFunc(ht, key);
while (ht->_tables[index]._status == EXITS)//线性探测
{
++index;
if (index == ht->_N)
{
index = 0;
}
}
ht->_tables[index]._key = key;
ht->_tables[index]._value = value;
ht->_tables[index]._status = EXITS;
ht->_size++;
}
void HashTableDestory(HashTable* ht)
{
assert(ht);
free(ht->_tables);
ht->_size = 0;
ht->_tables = 0;
}
HashNode* HashTableFind(HashTable* ht, KeyType key)
{
assert(ht);
size_t index = HashFunc(ht, key);
size_t index_next = index + 1;
if (ht->_tables[index]._status == EXITS && ht->_tables[index]._key == key)
{
return ht->_tables + index;
}
while (ht->_tables[index_next]._status != EMPTY)
{
if (index_next == index)
{
break;
}
if (ht->_tables[index_next]._key == key)
{
if (ht->_tables[index_next]._status == EXITS)
{
return ht->_tables + index_next;
}
else
{
return NULL;
}
}
index++;
if (index_next == ht->_N)
{
index_next = 0;
}
}
return NULL;
}
int HashTableRemove(HashTable* ht, KeyType key)
{
HashNode* node = HashTableFind(ht, key);
if (node)
{
node->_status = DELETE;
--ht->_size;
return 1;
}
else
{
return -1;
}
}
void Printhash(HashTable* ht)
{
for (size_t i = 0; i < ht->_N; i++)
{
printf("%d-->%d\n",ht->_tables[i]._key,ht->_tables[i]._status);
}
}
数据结构—哈希表开放地址发(数据类型int)
最新推荐文章于 2020-10-25 12:46:43 发布