- 论坛徽章:
- 0
|
本帖最后由 三月廿七 于 2011-10-30 09:06 编辑
- #ifndef HASHTABLE_H_
- #define HASHTABLE_H_
- typedef struct xHashTable* HashTable;
- /*
- * 哈希函数
- */
- typedef unsigned int (*hashFunction)(const void* key, int capacity);
- /*
- * 比较函数
- */
- typedef int (*compareFunction)(const void* a, const void* b);
- /*
- * 显示函数
- */
- typedef void (*showFunction)(const void* key, const void* item);
- /*
- * 键复制函数
- */
- typedef void*(*keyCloneFunction)(void* key);
- /*
- * 项复制函数
- */
- typedef void*(*itemCloneFunction)(void* item);
- /*
- * 键释放函数
- */
- typedef void (*keyDeleteFunction)(void* key);
- /*
- * 项释放函数
- */
- typedef void (*itemDeleteFunction)(void* item);
- /*
- * 构造哈希表
- */
- HashTable HASHTABLEnew(int max, int number, hashFunction hash,
- compareFunction compare, showFunction show,
- keyCloneFunction keyClone, itemCloneFunction itemClone,
- keyDeleteFunction keyDelete, itemDeleteFunction itemDelete);
- /**
- * 释放哈希表
- */
- void HASHTABLEdelete(HashTable hashTable);
- /**
- * 添加项
- */
- int HASHTABLEinsert(HashTable hashTable, void* key, void* item);
- /**
- * 查找项
- */
- void* HASHTABLEsearch(HashTable hashTable, void* key);
- /**
- * 删除项
- */
- int HASHTABLEremove(HashTable hashTable, void* key);
- /**
- * 重设哈希表大小
- */
- int HASHTABLEresize(HashTable hashTable, int size);
- /**
- * 遍历哈希表
- */
- void HASHTABLEtraverse(HashTable hashTable);
- #endif
复制代码- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include "HashTable.h"
- #define TRUE 1
- #define FALSE 0
- typedef struct xHashTableNode HASHTABLEnode;
- typedef HASHTABLEnode* HashTableNode;
- struct xHashTableNode
- {
- void* key;
- void* item;
- HashTableNode next;
- } ;
- typedef struct xHashTableChain HASHTABLEchain;
- typedef HASHTABLEchain* HashTableChain;
- struct xHashTableChain
- {
- // 分离链中的第一个链接
- HashTableNode head;
- // 分离链的长度
- int size;
- } ;
- typedef struct xHashTable HASHTABLE;
- struct xHashTable
- {
- // 分离链表
- HashTableChain* table;
- // 项的最大个数
- int max;
- // 平均每个链中的项的个数
- int number;
- // 项的个数
- int size;
- // 分离链个数
- int capacity;
- hashFunction hash;
- compareFunction compare;
- showFunction show;
- keyCloneFunction keyClone;
- itemCloneFunction itemClone;
- keyDeleteFunction keyDelete;
- itemDeleteFunction itemDelete;
- };
- static HashTableNode HASHTABLENODEnew(void* key, void* item, HashTableNode next)
- {
- HashTableNode node = malloc(sizeof * node);
- if (node == NULL)
- {
- return NULL;
- }
- node->key = key;
- node->item = item;
- node->next = next;
- return node;
- }
- static HashTableChain HASHTABLECHAINnew(void)
- {
- HashTableChain chain = malloc(sizeof * chain);
- if (chain == NULL)
- {
- return NULL;
- }
- chain->head = NULL;
- chain->size = 0;
- return chain;
- }
- HashTable HASHTABLEnew(int max, int number, hashFunction hash,
- compareFunction compare, showFunction show,
- keyCloneFunction keyClone, itemCloneFunction itemClone,
- keyDeleteFunction keyDelete, itemDeleteFunction itemDelete)
- {
- HashTable hashTable = malloc(sizeof * hashTable);
- int i, c;
- if (hashTable == NULL)
- {
- return NULL;
- }
- c = max / number;
- hashTable->table = malloc(c * sizeof * hashTable->table);
- if (hashTable->table == NULL)
- {
- free(hashTable);
- return NULL;
- }
- for (i = 0; i < c; i++)
- {
- hashTable->table[i] = NULL;
- }
- hashTable->max = max;
- hashTable->number = number;
- hashTable->size = 0;
- hashTable->capacity = c;
- hashTable->show = show;
- hashTable->hash = hash;
- hashTable->compare = compare;
- hashTable->keyClone = keyClone;
- hashTable->itemClone = itemClone;
- hashTable->keyDelete = keyDelete;
- hashTable->itemDelete = itemDelete;
- return hashTable;
- }
- void HASHTABLEdelete(HashTable hashTable)
- {
- int i;
- assert(hashTable);
- for (i = 0; i < hashTable->capacity; i++)
- {
- HashTableNode save, it;
- if (hashTable->table[i] == NULL)
- {
- continue;
- }
- it = hashTable->table[i]->head;
- for (; it != NULL; it = save)
- {
- save = it->next;
- hashTable->keyDelete(it->key);
- hashTable->itemDelete(it->item);
- free(it);
- }
- free(hashTable->table[i]);
- }
- free(hashTable->table);
- free(hashTable);
- }
- void* HASHTABLEsearch(HashTable hashTable, void* key)
- {
- unsigned int h;
- assert(hashTable);
- h = hashTable->hash(key, hashTable->capacity);
- if (hashTable->table[h] != NULL)
- {
- HashTableNode it = hashTable->table[h]->head;
- for (; it != NULL; it = it->next)
- {
- if (hashTable->compare(key, it->key) == 0)
- {
- return it->item;
- }
- }
- }
- return NULL;
- }
- int HASHTABLEinsert(HashTable hashTable, void* key, void* item)
- {
- unsigned int h;
- void* tempKey, *tempItem;
- HashTableNode tempNode;
- assert(hashTable);
- h = hashTable->hash(key, hashTable->capacity);
- // 不允许重复项
- if (HASHTABLEsearch(hashTable, key) != NULL)
- {
- return FALSE;
- }
- tempKey = hashTable->keyClone(key);
- tempItem = hashTable->itemClone(item);
- tempNode = HASHTABLENODEnew(tempKey, tempItem, NULL);
- if (tempNode == NULL)
- {
- return FALSE;
- }
- if (hashTable->table[h] == NULL)
- {
- hashTable->table[h] = HASHTABLECHAINnew();
- if (hashTable->table[h] == NULL)
- {
- hashTable->keyDelete(tempNode->key);
- hashTable->itemDelete(tempNode->item);
- free(tempNode);
- return FALSE;
- }
- }
- tempNode->next = hashTable->table[h]->head;
- hashTable->table[h]->head = tempNode;
- hashTable->table[h]->size++;
- hashTable->size++;
- if (hashTable->size > hashTable->max / 2)
- {
- if (!HASHTABLEresize(hashTable, hashTable->max * 2))
- {
- return FALSE;
- }
- }
- return TRUE;
- }
- int HASHTABLEremove(HashTable hashTable, void* key)
- {
- unsigned int h;
- HashTableNode save, it;
- assert(hashTable);
- h = hashTable->hash(key, hashTable->capacity);
- if (hashTable->table[h] == NULL)
- {
- return FALSE;
- }
- it = hashTable->table[h]->head;
- if (hashTable->compare(key, it->key) == 0)
- {
- hashTable->table[h]->head = it->next;
- hashTable->keyDelete(it->key);
- hashTable->itemDelete(it->item);
- free(it);
- if (hashTable->table[h]->head == NULL)
- {
- free(hashTable->table[h]);
- hashTable->table[h] = NULL;
- }
- else
- {
- hashTable->table[h]->size--;
- }
- }
- else
- {
- while (it->next != NULL)
- {
- if (hashTable->compare(key, it->next->key) == 0)
- {
- break;
- }
- it = it->next;
- }
- if (it->next == NULL)
- {
- return FALSE;
- }
- save = it->next;
- it->next = it->next->next;
- hashTable->keyDelete(save->key);
- hashTable->itemDelete(save->item);
- free(save);
- hashTable->table[h]->size--;
- }
- hashTable->size--;
- return TRUE;
- }
- static TABLEfree(HashTable hashTable)
- {
- HashTableNode it, save;
- int i;
- for (i = 0; i < hashTable->capacity; i++)
- {
- if (hashTable->table[i] == NULL)
- {
- continue;
- }
- it = hashTable->table[i]->head;
- for (; it != NULL; it = save)
- {
- save = it->next;
- hashTable->keyDelete(it->key);
- hashTable->itemDelete(it->item);
- free(it);
- }
- free(hashTable->table[i]);
- }
- free(hashTable->table);
- }
- int HASHTABLEresize(HashTable hashTable, int size)
- {
- HashTableChain* table;
- HashTableNode it;
- void* tempKey, *tempItem;
- HashTableNode tempNode;
- int i, c;
- unsigned int h;
-
- c = size / hashTable->number;
- table = malloc(c * sizeof * table);
- if (table == NULL)
- {
- return FALSE;
- }
- for (i = 0; i < c; i++)
- {
- table[i] = NULL;
- }
- for (i = 0; i < hashTable->capacity; i++)
- {
- if (hashTable->table[i] == NULL)
- {
- continue;
- }
- for (it = hashTable->table[i]->head; it != NULL; it = it->next)
- {
- h = hashTable->hash(it->key, c);
- if (table[h] == NULL)
- {
- table[h] = HASHTABLECHAINnew();
- if (table[h] == NULL)
- {
- return FALSE;
- }
- }
- tempKey = hashTable->keyClone(it->key);
- tempItem = hashTable->itemClone(it->item);
- tempNode = HASHTABLENODEnew(tempKey, tempItem, NULL);
- tempNode->next = table[h]->head;
- table[h]->head = tempNode;
- table[h]->size++;
- }
- }
- TABLEfree(hashTable);
- hashTable->table = table;
- hashTable->max = size;
- hashTable->capacity = c;
- return TRUE;
- }
- void HASHTABLEtraverse(HashTable hashTable)
- {
- int i;
- assert(hashTable);
- for (i = 0; i < hashTable->capacity; i++)
- {
- HashTableNode it;
- if (hashTable->table[i] == NULL)
- {
- continue;
- }
- it = hashTable->table[i]->head;
- for (; it != NULL; it = it->next)
- {
- hashTable->show(it->key, it->item);
- }
- printf("\n");
- }
- }
复制代码- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "HashTable.h"
- unsigned int STRINGhash(const void* key, int capacity);
- int STRINGcompare(const void* a, const void* b);
- void STRINGshow(const void* key, const void* item);
- void* STRINGkeyClone(void* key);
- void* STRINGitemClone(void* item);
- void STRINGkeyDelete(void* key);
- void STRINGitemDelete(void* item);
- int main(void)
- {
- HashTable hashTable = HASHTABLEnew(10, 5, STRINGhash,
- STRINGcompare, STRINGshow,
- STRINGkeyClone, STRINGitemClone,
- STRINGkeyDelete, STRINGitemDelete);
- HASHTABLEinsert(hashTable, "BlueGuy0", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy1", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy2", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy3", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy4", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy5", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy6", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy7", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy8", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy9", "920170678");
- HASHTABLEinsert(hashTable, "BlueGuy ", "920170678");
- HASHTABLEtraverse(hashTable);
- HASHTABLEdelete(hashTable);
- getchar();
- return 0;
- }
- unsigned int STRINGhash(const void* key, int capacity)
- {
- unsigned int h = 0, a = 255;
- unsigned char* str = (unsigned char*)key;
- for (; *str ; str++)
- {
- h = (a * h + *str) % capacity;
- }
- return h;
- }
- int STRINGcompare(const void* a, const void* b)
- {
- const char* a1 = (const char*) a;
- const char* a2 = (const char*) b;
- return strcmp(a1, a2);
- }
- void STRINGshow(const void* key, const void* item)
- {
- const char* a1 = (const char*) key;
- const char* a2 = (const char*) item;
- printf("%s: %s\n", a1, a2);
- }
- void* STRINGkeyClone(void* key)
- {
- return key;
- }
- void* STRINGitemClone(void* item)
- {
- return item;
- }
- void STRINGkeyDelete(void* key)
- {
- }
- void STRINGitemDelete(void* item)
- {
- }
复制代码 |
|