教你從零開始寫一個哈希表--哈希表結構

  每一個鍵-值對(items)都會被保存在結構體中:

// hash_table.h
typedef struct {
    char* key;
    char* value;
} ht_item;

  哈希表保存了一組鍵值對的指針,以及哈希表大小的一些細節和它的負載:

// hash_table.h
typedef struct {
    int size;
    int count;
    ht_item** items;
} ht_hash_table;

初始化和刪除

  這裏需要爲ht_item定義初始化函數。這個函數分配了ht_item大小的內存,同時在新的內存塊中保存了字符串kv的副本。此處把這個函數標記爲static,是因爲它只會被哈希表在內部調用一次。

// hash_table.c
#include <stdlib.h>
#include <string.h>

#include "hash_table.h"

static ht_item* ht_new_item(const char* k, const char* v) {
    ht_item* i = malloc(sizeof(ht_item));
    i->key = strdup(k);
    i->value = strdup(v);
    return i;
}

  ht_new函數初始化了一個新的哈希表。size變量定義了哈希表可以保存多少個鍵值對。此處定爲53個,至於如何在後面程序中更改size,教程會在《調整大小》一節中詳細介紹。我們用calloc函數初始化一組鍵值對。calloc這個函數用NULL對分配的內存進行填充。數組的首位存儲是NULL意味着這個桶是空的。

// hash_table.c
ht_hash_table* ht_new() {
    ht_hash_table* ht = malloc(sizeof(ht_hash_table));

    ht->size = 53;
    ht->count = 0;
    ht->items = calloc((size_t)ht->size, sizeof(ht_item*));
    return ht;
}

  我們也需要函數來刪除ht_items變量和ht_hash+tables結構。這將會釋放已經分配的內存,不然就會導致內存泄漏。

// hash_table.c
static void ht_del_item(ht_item* i) {
    free(i->key);
    free(i->value);
    free(i);
}


void ht_del_hash_table(ht_hash_table* ht) {
    for (int i = 0; i < ht->size; i++) {
        ht_item* item = ht->items[i];
        if (item != NULL) {
            ht_del_item(item);
        }
    }
    free(ht->items);
    free(ht);
}

  哈希表的代碼已經初具原型,它足以實現創建和銷燬一個哈希表。儘管它此刻還做不了什麼事情,但我們依然可以試着運行一下這份代碼。

// main.c
#include "hash_table.h"

int main() {
    ht_hash_table* ht = ht_new();
    ht_del_hash_table(ht);
}

上一篇:教你從零開始寫一個哈希表–導讀
下一篇:教你從零開始寫一個哈希表–哈希函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章