ハッシュ テーブルは、一定時間内にアイテムを検索できるデータ構造です。値をハッシュし、その値を配列内のオフセットに変換することで機能します。ハッシュ テーブルの概念は非常に理解しやすいですが、実装は明らかに困難です。ここにハッシュ テーブル全体を貼り付けるわけではありませんが、数週間前に C で作成したハッシュ テーブルの一部を以下に示します...
ハッシュ テーブルを作成するための基本の 1 つは、優れたハッシュ関数を使用することです。ハッシュ テーブルで djb2 ハッシュ関数を使用しました。
int ComputeHash(char* key)
{
int hash = 5381;
while (*key)
hash = ((hash << 5) + hash) + *(key++);
return hash % hashTable.totalBuckets;
}
次に、テーブル内のバケットを作成および管理するための実際のコード自体が続きます
typedef struct HashTable{
HashTable* nextEntry;
char* key;
char* value;
}HashBucket;
typedef struct HashTableEntry{
int totalBuckets; // Total number of buckets allocated for the hash table
HashTable** hashBucketArray; // Pointer to array of buckets
}HashTableEntry;
HashTableEntry hashTable;
bool InitHashTable(int totalBuckets)
{
if(totalBuckets > 0)
{
hashTable.totalBuckets = totalBuckets;
hashTable.hashBucketArray = (HashTable**)malloc(totalBuckets * sizeof(HashTable));
if(hashTable.hashBucketArray != NULL)
{
memset(hashTable.hashBucketArray, 0, sizeof(HashTable) * totalBuckets);
return true;
}
}
return false;
}
bool AddNode(char* key, char* value)
{
int offset = ComputeHash(key);
if(hashTable.hashBucketArray[offset] == NULL)
{
hashTable.hashBucketArray[offset] = NewNode(key, value);
if(hashTable.hashBucketArray[offset] != NULL)
return true;
}
else
{
if(AppendLinkedNode(hashTable.hashBucketArray[offset], key, value) != NULL)
return true;
}
return false;
}
HashTable* NewNode(char* key, char* value)
{
HashTable* tmpNode = (HashTable*)malloc(sizeof(HashTable));
if(tmpNode != NULL)
{
tmpNode->nextEntry = NULL;
tmpNode->key = (char*)malloc(strlen(key));
tmpNode->value = (char*)malloc(strlen(value));
strcpy(tmpNode->key, key);
strcpy(tmpNode->value, value);
}
return tmpNode;
}
AppendLinkedNode は、リンクされたリストの最後のノードを見つけて、それに新しいノードを追加します。
コードは次のように使用されます。
if(InitHashTable(100) == false) return -1;
AddNode("10", "TEN");
ノードの検索は次のように簡単です。
HashTable* FindNode(char* key)
{
int offset = ComputeHash(key);
HashTable* tmpNode = hashTable.hashBucketArray[offset];
while(tmpNode != NULL)
{
if(strcmp(tmpNode->key, key) == 0)
return tmpNode;
tmpNode = tmpNode->nextEntry;
}
return NULL;
}
そして、次のように使用されます。
char* value = FindNode("10");