赞
踩
哈希桶又被称作开链法,开散列法。相比于闭散列法哈希桶更为灵活直观,存数据时不会浪费空间,开散列法存数据时由于避免哈希冲突,总会有百分之三十的空间浪费,当存储空间很大时将会造成大量的浪费。同时开散列法造成哈希冲突时不便于查找数据。所以我们有了哈希结构中的哈希桶。
哈希桶与开散列法一样的是需要开一段数组用于映射,不过不一样的是哈希桶的数组存的是指针所以哈希桶是一段指针数组。数组中每一个位置都存着一段链表,当插入数据时不用处理哈希冲突,直接将数据链接在链表即可,哈希桶的结构如下所示。
虽然哈希桶不会有哈希冲突,不过当一个桶中存在的数据过多时,也会造成查找的不便。于是我们根据此设计了哈希桶的负载因子,一般是控制在1左右,即size/N=1。当超过负载因子时进行扩容。
##哈希桶函数设计
哈希桶函数设计如下:
首先定义哈希桶结构体
typedef int ValueType; typedef struct HashNode { KeyType _key; ValueType _value; struct HashNode* _next; }HashNode; typedef struct HashTable { HashNode** _tables; size_t _size; size_t _N; }HashTable;
{
ht->_N = GetNextPrimeNum(N);
ht->_tables = (HashNode**)malloc(sizeof(HashNode*)*ht->_N);
ht->_size = 0;
for (int i = 0;i < ht->_N;i++)
{
ht->_tables[i] = NULL;
}
}
HashNode* BuyHashNode(KeyType key, ValueType value)
{
HashNode* newnode;
newnode = (HashNode*)malloc(sizeof(HashNode));
newnode->_key = key;
newnode->_value = value;
newnode->_next = NULL;
return newnode;
}
void HashInsertCapacity(HashTable* ht) { if (ht->_N == ht->_size) { HashTable newht; HashTableInit(&newht,ht->_N); for (int i = 0;i < ht->_N;i++) { HashNode* ptr = ht->_tables[i]; while (ptr != NULL) { HashNode* cur = ptr; ptr = ptr->_next; cur->_next = newht._tables[HashFunc(cur->_key,newht._N)]; newht._tables[HashFunc(cur->_key, newht._N)] = cur; } } free(ht->_tables); ht->_N = newht._N; ht->_tables = newht._tables; } }
int HashTableInsert(HashTable* ht, KeyType key, ValueType value) { HashInsertCapacity(ht); int index = HashFunc(key, ht->_N); HashNode* cur = ht->_tables[index]; while (cur != NULL) { if (cur->_key == key) { return -1; } cur=cur->_next; } HashNode* newnode = BuyHashNode(key, value); newnode->_next = ht->_tables[index]; ht->_tables[index] = newnode; ht->_size++; return 0; }
HashNode* HashTableFind(HashTable* ht, KeyType key)
{
int index = HashFunc(key,ht->_N);
HashNode* cur = ht->_tables[index];
while (cur != NULL)
{
if (cur->_key == key)
{
return cur;
}
}
return NULL;
}
int HashTableRemove(HashTable* ht, KeyType key) { int index = HashFunc(key,ht->_N); HashNode* prev = ht->_tables[index]; HashNode* ptr = ht->_tables[index]->_next; if (ptr == NULL) { if(prev->_key == key) { free(prev); ht->_tables[index] = NULL; return 0; } else { return -1; } } while (ptr != NULL) { if (ptr->_key == key) { prev->_next = ptr->_next; free(ptr); ht->_size--; return 0; } ptr = ptr->_next; } return -1; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。