1. 哈希表
1.1 Makefile
.PHONY: clean
CC = gcc
CFLAGS = -g -Wall -DDEBUG
EXTRA_FLAGS = -DUSE_SQUARE_DECTIVE
SOURCE = $(wildcard ./*.c)
BIN = $(patsubst %.c, %, $(notdir $(SOURCE)))
$(BIN): $(SOURCE)
$(CC) $(CFLAGS) $(EXTRA_FLAGS) $(SOURCE) -o $@
clean:
rm -rf $(BIN)
1.2 hash_table.h
#ifndef __HASH_TABLE_H__
#define __HASH_TABLE_H__
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int key_t;
typedef int value_t;
typedef struct {
key_t key;
value_t value;
} kv_pair_t;
typedef enum {
EMPTY_DATA = 0,
EXIST_DATA,
DELETED_DATA
} state_e;
typedef enum {
HASH_TABLE_OK = 0,
HASH_TABLE_NOT_FOUND = -0x0001,
HASH_TABLE_ERR_NULL_POINTER = -0x0002,
HASH_TABLE_ERR_CREATE_HEAP_FAILED = -0x0003,
HASH_TABLE_NO_CAPACITY = -0x0004,
HASH_TABLE_ERR_EXPANSION_FAILED = -0x0005,
HASH_TABLE_ERR_UNKNOWN = -0X0006
} hash_table_error_code_e;
typedef struct {
state_e state;
kv_pair_t kv_data;
} hash_data_t;
typedef size_t (*hash_func_handler)(key_t, size_t);
typedef struct {
hash_data_t *hash_data;
size_t capacity;
size_t size;
hash_func_handler hash_func;
} hash_table_t;
size_t mod_func(key_t key, size_t capacity);
hash_table_error_code_e hash_table_init(hash_table_t *hash_table,
size_t capacity,
hash_func_handler hash_func);
size_t get_hash_table_capacity(const hash_table_t *hash_table);
size_t get_hash_table_size(const hash_table_t *hash_table);
void print_hash_table(const hash_table_t *hash_table);
size_t hash_table_find_by_key(const hash_table_t *hash_table, key_t key);
value_t get_value_by_key(const hash_table_t *hash_table, key_t key);
hash_table_error_code_e hash_table_insert_kv_pair(hash_table_t *hash_table,
key_t key,
value_t value);
hash_table_error_code_e hash_table_remove_by_key(hash_table_t *hash_table, key_t key);
void hash_table_destroy(hash_table_t *hash_table);
#ifdef __cplusplus
}
#endif
#endif
1.3 hash_table.c
#include "hash_table.h"
static size_t get_next_prime_number(size_t num)
{
size_t i = 0;
static const size_t prime_list[] = {
11ul, 23ul, 37ul, 47ul,
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 (i = 0; i < sizeof(prime_list) / sizeof(size_t); ++i) {
if (prime_list[i] >= num) {
return prime_list[i];
}
}
return (size_t)-1;
}
size_t mod_func(key_t key, size_t capacity)
{
return (size_t)key % capacity;
}
#ifdef USE_SQUARE_DECTIVE
static size_t square_dective(size_t index, size_t capacity, size_t times)
{
return mod_func(index + times * times, capacity);
}
#else
static size_t linear_dective(size_t index, size_t capacity)
{
return mod_func(++index, capacity);
}
#endif
hash_table_error_code_e hash_table_init(hash_table_t *hash_table,
size_t capacity,
hash_func_handler hash_func)
{
hash_table_error_code_e ret = HASH_TABLE_OK;
size_t i = 0;
do {
if (NULL == hash_table) {
printf("hash_table is NULL\n");
ret = HASH_TABLE_ERR_NULL_POINTER;
break;
}
capacity = get_next_prime_number(capacity);
if ((size_t)-1 == capacity) {
printf("get_next_prime_number fail\n");
ret = HASH_TABLE_NO_CAPACITY;
break;
}
hash_table->hash_data = (hash_data_t *)calloc(1, sizeof(hash_data_t) * capacity);
if (NULL == hash_table->hash_data) {
perror("calloc hash_table->hash_data fail");
ret = HASH_TABLE_ERR_CREATE_HEAP_FAILED;
break;
}
hash_table->size = 0;
hash_table->capacity = capacity;
hash_table->hash_func = hash_func;
for (i = 0; i < capacity; ++i) {
hash_table->hash_data[i].state = EMPTY_DATA;
}
} while (0);
return ret;
}
size_t get_hash_table_capacity(const hash_table_t *hash_table)
{
return hash_table ? hash_table->capacity : 0;
}
size_t get_hash_table_size(const hash_table_t *hash_table)
{
return hash_table ? hash_table->size : 0;
}
char *enum_state_2_strings(state_e state)
{
char *state_strings = NULL;
switch (state) {
case EMPTY_DATA:
state_strings = "EMPTY";
break;
case EXIST_DATA:
state_strings = "EXIST";
break;
case DELETED_DATA:
state_strings = "DELETE";
break;
default:
break;
}
return state_strings;
}
void print_hash_table(const hash_table_t *hash_table)
{
if (NULL == hash_table || NULL == hash_table->hash_data) {
printf("hash_table or hash_table->hash_data is NULL\n");
return;
}
size_t i = 0, capacity = get_hash_table_capacity(hash_table);
for (i = 0; i < capacity; ++i) {
printf("hash table[%zu] ===> state: %s, key: %d, value: %d\n",
i,
enum_state_2_strings(hash_table->hash_data[i].state),
hash_table->hash_data[i].kv_data.key,
hash_table->hash_data[i].kv_data.value);
}
}
size_t hash_table_find_by_key(const hash_table_t *hash_table, key_t key)
{
if (NULL == hash_table) {
printf("hash_table is NULL\n");
return (size_t)HASH_TABLE_NOT_FOUND;
}
#ifdef USE_SQUARE_DECTIVE
size_t start = 0, times = 1;
#endif
size_t index = hash_table->hash_func(key, hash_table->capacity);
while (EMPTY_DATA != hash_table->hash_data[index].state) {
if ((key == hash_table->hash_data[index].kv_data.key)
&& (EXIST_DATA == hash_table->hash_data[index].state)) {
printf("same key = %d, exist data\n", key);
return index;
} else {
#ifndef USE_SQUARE_DECTIVE
index = linear_dective(index, hash_table->capacity);
#else
index = square_dective(start, hash_table->capacity, times);
++times;
#endif
}
}
printf("%s not found %d\n", __func__, key);
return (size_t)HASH_TABLE_NOT_FOUND;
}
value_t get_value_by_key(const hash_table_t *hash_table, key_t key)
{
value_t value = INT_MIN;
hash_table_error_code_e ret = hash_table_find_by_key(hash_table, key);
if ((size_t)HASH_TABLE_NOT_FOUND != ret) {
value = hash_table->hash_data[ret].kv_data.value;
}
return value;
}
static hash_table_error_code_e rehash(hash_table_t *hash_table)
{
hash_table_error_code_e ret = HASH_TABLE_OK;
do {
if (NULL == hash_table) {
printf("hash_table is NULL\n");
ret = HASH_TABLE_ERR_NULL_POINTER;
break;
}
if ((hash_table->size) * 10 / (hash_table->capacity) < 7) {
printf("hash_table do not need rehash\n");
break;
}
size_t i = 0;
hash_table_t new_hash_table;
size_t capacity = hash_table->capacity * 2;
if (HASH_TABLE_OK != hash_table_init(&new_hash_table, capacity, hash_table->hash_func)) {
printf("hash_table_init new_hash_table fail\n");
ret = HASH_TABLE_ERR_UNKNOWN;
break;
}
for (i = 0; i < hash_table->capacity; ++i) {
if (EXIST_DATA == hash_table->hash_data[i].state) {
if (HASH_TABLE_OK != hash_table_insert_kv_pair(&new_hash_table,
hash_table->hash_data[i].kv_data.key,
hash_table->hash_data[i].kv_data.value)) {
printf("hash_table_insert_kv_pair fail\n");
return HASH_TABLE_ERR_UNKNOWN;
}
}
}
free(hash_table->hash_data);
hash_table->hash_data = new_hash_table.hash_data;
hash_table->capacity = new_hash_table.capacity;
} while (0);
return ret;
}
hash_table_error_code_e hash_table_insert_kv_pair(hash_table_t *hash_table,
key_t key,
value_t value)
{
hash_table_error_code_e ret = HASH_TABLE_OK;
do {
if (NULL == hash_table) {
printf("hash_table is NULL\n");
ret = HASH_TABLE_ERR_NULL_POINTER;
break;
}
if (HASH_TABLE_OK != rehash(hash_table)) {
printf("rehash fail\n");
ret = HASH_TABLE_ERR_EXPANSION_FAILED;
break;
}
size_t index = hash_table->hash_func(key, hash_table->capacity);
#ifdef USE_SQUARE_DECTIVE
size_t times = 1, start = index;
#endif
while (EXIST_DATA == hash_table->hash_data[index].state) {
if ((key == hash_table->hash_data[index].kv_data.key)) {
return HASH_TABLE_NOT_FOUND;
} else {
#ifndef USE_SQUARE_DECTIVE
index = linear_dective(index, hash_table->capacity);
#else
index = square_dective(start, hash_table->capacity, times);
++times;
#endif
}
}
hash_table->hash_data[index].kv_data.key = key;
hash_table->hash_data[index].kv_data.value = value;
hash_table->hash_data[index].state = EXIST_DATA;
++hash_table->size;
} while (0);
return ret;
}
hash_table_error_code_e hash_table_remove_by_key(hash_table_t *hash_table, key_t key)
{
if (NULL == hash_table) {
printf("hash_table is NULL\n");
return HASH_TABLE_ERR_NULL_POINTER;
}
size_t index = hash_table->hash_func(key, hash_table->capacity);
#ifdef USE_SQUARE_DECTIVE
size_t times = 1, start = index;
#endif
while (EMPTY_DATA != hash_table->hash_data[index].state) {
if ((key == hash_table->hash_data[index].kv_data.key)
&& (EXIST_DATA == hash_table->hash_data[index].state)) {
hash_table->hash_data[index].state = DELETED_DATA;
--hash_table->size;
return HASH_TABLE_OK;
} else {
#ifndef USE_SQUARE_DECTIVE
index = linear_dective(index, hash_table->capacity);
#else
index = square_dective(start, hash_table->capacity, times);
++times;
#endif
}
}
return HASH_TABLE_NOT_FOUND;
}
void hash_table_destroy(hash_table_t *hash_table)
{
if (NULL == hash_table) {
printf("hash_table is NULL\n");
return;
}
free(hash_table->hash_data);
hash_table->hash_data = NULL;
hash_table->capacity = 0;
hash_table->size = 0;
}
1.4 test_hash_table.c
#include "hash_table.h"
#include <time.h>
void test()
{
srand((unsigned int)time(NULL));
int i = 0;
hash_table_t hash_table;
#ifndef USE_SQUARE_DECTIVE
int numbers[] = {1, 19, 38, 27, 19, 30, 20, 73, 126, 13};
#else
int numbers[] = {0, 11, 22, 33, 44};
#endif
printf("hash table init\n");
if (HASH_TABLE_OK != hash_table_init(&hash_table,
sizeof(numbers) / sizeof(int),
mod_func)) {
printf("hash_table_init fail\n");
return;
}
printf("\nprint hash_table\n");
print_hash_table(&hash_table);
printf("hash table capacity: %zu\n", get_hash_table_capacity(&hash_table));
printf("hash table size: %zu\n", get_hash_table_size(&hash_table));
for (i = 0; i < sizeof(numbers) / sizeof(int); ++i) {
size_t index = hash_table_find_by_key(&hash_table, numbers[i]);
printf("index: %zu, numbers[%d]: %d\n", index, i, numbers[i]);
if ((size_t)HASH_TABLE_NOT_FOUND == index) {
int random_num = rand() % 100 + 1;
printf("random num: %d\n", random_num);
if (HASH_TABLE_OK != hash_table_insert_kv_pair(&hash_table,
numbers[i],
random_num)) {
printf("hash_table_insert_kv_pair failed, key: %d, value: %d\n",
numbers[i], random_num);
}
}
}
#ifndef USE_SQUARE_DECTIVE
printf("\nhash_table[%d]: %d\n", 1, get_value_by_key(&hash_table, 1));
printf("\nhash_table[%d]: %d\n", 19, get_value_by_key(&hash_table, 19));
printf("hash_table[%d]: %d\n", 72, get_value_by_key(&hash_table, 72));
printf("hash_table[%d]: %d\n", 33, get_value_by_key(&hash_table, 33));
#else
printf("\nhash_table[%d]: %d\n", 11, get_value_by_key(&hash_table, 11));
printf("\nhash_table[%d]: %d\n", 33, get_value_by_key(&hash_table, 33));
printf("hash_table[%d]: %d\n", 15, get_value_by_key(&hash_table, 15));
#endif
printf("\nprint hash_table\n");
print_hash_table(&hash_table);
printf("hash table capacity: %zu\n", get_hash_table_capacity(&hash_table));
printf("hash table size: %zu\n", get_hash_table_size(&hash_table));
if (HASH_TABLE_OK != hash_table_remove_by_key(&hash_table, 45)) {
printf("hash_table_remove_by_key failed, key: %d\n", 45);
}
printf("\nprint hash_table\n");
print_hash_table(&hash_table);
#ifndef USE_SQUARE_DECTIVE
if (HASH_TABLE_OK != hash_table_remove_by_key(&hash_table, 19)) {
printf("hash_table_remove_by_key failed, key: %d\n", 19);
}
#else
if (HASH_TABLE_OK != hash_table_remove_by_key(&hash_table, 44)) {
printf("hash_table_remove_by_key failed, key: %d\n", 44);
}
#endif
printf("\nprint hash_table\n");
print_hash_table(&hash_table);
if (HASH_TABLE_OK != hash_table_insert_kv_pair(&hash_table, 179, 666)) {
printf("hash_table_insert_kv_pair failed, key: %d, value: %d\n", 179, 666);
}
printf("\nprint hash_table\n");
print_hash_table(&hash_table);
printf("\nhash_table[%d]: %d\n", 179, get_value_by_key(&hash_table, 179));
printf("\nhash table destroy\n");
hash_table_destroy(&hash_table);
printf("hash table capacity: %zu\n", get_hash_table_capacity(&hash_table));
printf("hash table size: %zu\n", get_hash_table_size(&hash_table));
}
int main(void)
{
test();
return 0;
}
2. 哈希桶
2.1 Makefile
.PHONY: clean
CC = gcc
CFLAGS = -g -Wall -DDEBUG
SOURCE = $(wildcard ./*.c)
BIN = $(patsubst %.c, %, $(notdir $(SOURCE)))
$(BIN): $(SOURCE)
$(CC) $(CFLAGS) $(SOURCE) -o $@
clean:
rm -rf $(BIN)
2.2 hash_bucket.h
#ifndef __HASH_BUCKET_H__
#define __HASH_BUCKET_H__
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int key_t;
typedef int value_t;
typedef struct {
key_t key;
value_t value;
} kv_pair_t;
typedef enum {
HASH_BUCKET_OK = 0,
HASH_BUCKET_NOT_FOUND = -0x0001,
HASH_BUCKET_ERR_NULL_POINTER = -0x0002,
HASH_BUCKET_ERR_CREATE_HEAP_FAILED = -0x0003,
HASH_BUCKET_NO_CAPACITY = -0x0004
} hash_bucket_error_code_e;
typedef struct hash_data_s {
kv_pair_t kv_data;
struct hash_data_s *next;
} hash_data_t;
typedef size_t (*hash_func_handler)(key_t, size_t);
typedef struct {
hash_data_t **hash_data;
size_t capacity;
size_t size;
hash_func_handler hash_func;
} hash_bucket_t;
size_t mod_func(key_t key, size_t capacity);
hash_bucket_error_code_e hash_bucket_init(hash_bucket_t *hash_bucket,
size_t capacity,
hash_func_handler hash_func);
size_t get_hash_bucket_capacity(const hash_bucket_t *hash_bucket);
size_t get_hash_bucket_size(const hash_bucket_t *hash_bucket);
void print_hash_bucket(const hash_bucket_t *hash_bucket);
hash_data_t *hash_bucket_find_by_key(const hash_bucket_t *hash_bucket, key_t key);
value_t get_value_by_key(const hash_bucket_t *hash_bucket, key_t key);
hash_bucket_error_code_e hash_bucket_insert_kv_pair(hash_bucket_t *hash_bucket,
key_t key,
value_t value);
hash_bucket_error_code_e hash_bucket_remove_by_key(hash_bucket_t *hash_bucket, key_t key);
void hash_bucket_destroy(hash_bucket_t *hash_bucket);
#ifdef __cplusplus
}
#endif
#endif
2.3 hash_bucket.c
#include "hash_bucket.h"
static size_t get_next_prime_number(size_t num)
{
size_t i = 0;
static const size_t prime_list[] = {
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 (i = 0; i < sizeof(prime_list) / sizeof(size_t); ++i) {
if (prime_list[i] >= num) {
return prime_list[i];
}
}
return (size_t)-1;
}
size_t mod_func(key_t key, size_t capacity)
{
return (size_t)key % capacity;
}
hash_bucket_error_code_e hash_bucket_init(hash_bucket_t *hash_bucket,
size_t capacity,
hash_func_handler hash_func)
{
hash_bucket_error_code_e ret = HASH_BUCKET_OK;
size_t i = 0;
do {
if (NULL == hash_bucket) {
printf("hash_bucket is NULL\n");
ret = HASH_BUCKET_ERR_NULL_POINTER;
break;
}
capacity = get_next_prime_number(capacity);
if ((size_t)-1 == capacity) {
printf("get_next_prime_number fail\n");
ret = HASH_BUCKET_NO_CAPACITY;
break;
}
hash_bucket->hash_data = (hash_data_t **)calloc(1, sizeof(hash_data_t *) * capacity);
if (NULL == hash_bucket->hash_data) {
perror("calloc hash_bucket->hash_data fail");
ret = HASH_BUCKET_ERR_CREATE_HEAP_FAILED;
break;
}
hash_bucket->size = 0;
hash_bucket->capacity = capacity;
hash_bucket->hash_func = hash_func;
for (i = 0; i < capacity; ++i) {
hash_bucket->hash_data[i] = NULL;
}
} while (0);
return ret;
}
size_t get_hash_bucket_capacity(const hash_bucket_t *hash_bucket)
{
return hash_bucket ? hash_bucket->capacity : 0;
}
size_t get_hash_bucket_size(const hash_bucket_t *hash_bucket)
{
return hash_bucket ? hash_bucket->size : 0;
}
void print_hash_bucket(const hash_bucket_t *hash_bucket)
{
if (NULL == hash_bucket || NULL == hash_bucket->hash_data) {
printf("hash_bucket or hash_bucket->hash_data is NULL\n");
return;
}
size_t i = 0, capacity = get_hash_bucket_capacity(hash_bucket);
hash_data_t *cur = NULL;
for (i = 0; i < capacity; ++i) {
printf("hash bucket[%zu] -> ", i);
for (cur = hash_bucket->hash_data[i]; NULL != cur; cur = cur->next) {
printf("{%d : %d} -> ", cur->kv_data.key, cur->kv_data.value);
}
printf("NULL\n");
}
}
hash_data_t *hash_bucket_find_by_key(const hash_bucket_t *hash_bucket, key_t key)
{
hash_data_t *cur = NULL;
if (NULL == hash_bucket) {
printf("hash_bucket is NULL\n");
return NULL;
}
size_t index = hash_bucket->hash_func(key, hash_bucket->capacity);
for (cur = hash_bucket->hash_data[index]; NULL != cur; cur = cur->next) {
if (key == cur->kv_data.key) {
return cur;
}
}
printf("not found %d\n", key);
return NULL;
}
value_t get_value_by_key(const hash_bucket_t *hash_bucket, key_t key)
{
value_t value = INT_MIN;
hash_data_t *found = hash_bucket_find_by_key(hash_bucket, key);
if (NULL != found) {
return found->kv_data.value;
}
return value;
}
hash_bucket_error_code_e hash_bucket_insert_kv_pair(hash_bucket_t *hash_bucket,
key_t key,
value_t value)
{
hash_bucket_error_code_e ret = HASH_BUCKET_OK;
do {
if (NULL == hash_bucket) {
printf("hash_bucket is NULL\n");
ret = HASH_BUCKET_ERR_NULL_POINTER;
break;
}
size_t index = hash_bucket->hash_func(key, hash_bucket->capacity);
hash_data_t *cur = NULL, *new_hash_data = NULL;
for (cur = hash_bucket->hash_data[index]; NULL != cur; cur = cur->next) {
if (key == cur->kv_data.key) {
return HASH_BUCKET_NOT_FOUND;
}
}
new_hash_data = (hash_data_t *)calloc(1, sizeof(hash_data_t));
if (NULL == new_hash_data) {
perror("calloc new_hash_data fail");
ret = HASH_BUCKET_ERR_CREATE_HEAP_FAILED;
break;
}
new_hash_data->kv_data.key = key;
new_hash_data->kv_data.value = value;
++hash_bucket->size;
new_hash_data->next = hash_bucket->hash_data[index];
hash_bucket->hash_data[index] = new_hash_data;
} while (0);
return ret;
}
hash_bucket_error_code_e hash_bucket_remove_by_key(hash_bucket_t *hash_bucket, key_t key)
{
if (NULL == hash_bucket) {
printf("hash_bucket is NULL\n");
return HASH_BUCKET_ERR_NULL_POINTER;
}
size_t index = hash_bucket->hash_func(key, hash_bucket->capacity);
hash_data_t *cur = NULL, *tmp_hash_data = NULL, *next_hash_data = NULL;
for (cur = hash_bucket->hash_data[index]; NULL != cur; cur = next_hash_data) {
next_hash_data = cur->next;
if (key == cur->kv_data.key) {
if (NULL == tmp_hash_data) {
hash_bucket->hash_data[index] = next_hash_data;
} else {
tmp_hash_data->next = next_hash_data;
}
free(cur);
--hash_bucket->size;
return HASH_BUCKET_OK;
} else {
tmp_hash_data = cur;
}
}
return HASH_BUCKET_NOT_FOUND;
}
void hash_bucket_destroy(hash_bucket_t *hash_bucket)
{
if (NULL == hash_bucket) {
printf("hash_bucket is NULL\n");
return;
}
size_t i = 0;
hash_data_t *cur = NULL, *next_data = NULL;
for (i = 0; i < hash_bucket->capacity; ++i) {
for (cur = hash_bucket->hash_data[i]; NULL != cur; cur = next_data) {
next_data = cur->next;
free(cur);
}
}
free(hash_bucket->hash_data);
hash_bucket->hash_data = NULL;
hash_bucket->capacity = 0;
hash_bucket->size = 0;
}
2.4 test_hash_bucket.c
#include "hash_bucket.h"
#include <time.h>
void test()
{
hash_bucket_t hash_bucket;
size_t i = 0;
hash_data_t *found = NULL;
int numbers[] = {1, 23, 46, 53, 106, 34, 11, 2, 34, 55};
srand((unsigned int)time(NULL));
printf("hash bucket init\n");
if (HASH_BUCKET_OK != hash_bucket_init(&hash_bucket,
sizeof(numbers) / sizeof(int),
mod_func)) {
printf("hash_bucket_init fail\n");
return;
}
printf("\nprint hash_bucket\n");
print_hash_bucket(&hash_bucket);
printf("hash table capacity: %zu\n", get_hash_bucket_capacity(&hash_bucket));
printf("hash table size: %zu\n", get_hash_bucket_size(&hash_bucket));
for (i = 0; i < sizeof(numbers) / sizeof(int); ++i) {
found = hash_bucket_find_by_key(&hash_bucket, numbers[i]);
if (NULL == found) {
int random_num = rand() % 100 + 1;
printf("random num: %d\n", random_num);
if (HASH_BUCKET_OK != hash_bucket_insert_kv_pair(&hash_bucket,
numbers[i],
random_num)) {
printf("hash_bucket_insert_kv_pair failed, key: %d, value: %d\n",
numbers[i], random_num);
}
}
}
printf("\nhash_bucket[%d]: %d\n", 55, get_value_by_key(&hash_bucket, 55));
printf("hash_bucket[%d]: %d\n", 33, get_value_by_key(&hash_bucket, 33));
printf("\nprint hash_bucket\n");
print_hash_bucket(&hash_bucket);
printf("hash table capacity: %zu\n", get_hash_bucket_capacity(&hash_bucket));
printf("hash table size: %zu\n", get_hash_bucket_size(&hash_bucket));
printf("\nhash_bucket_remove_by_key\n");
if (HASH_BUCKET_OK != hash_bucket_remove_by_key(&hash_bucket, 1)) {
printf("hash_bucket_remove_by_key failed, key: %d\n", 1);
}
if (HASH_BUCKET_OK != hash_bucket_remove_by_key(&hash_bucket, 106)) {
printf("hash_bucket_remove_by_key failed, key: %d\n", 106);
}
printf("\nprint hash_bucket\n");
print_hash_bucket(&hash_bucket);
printf("hash table capacity: %zu\n", get_hash_bucket_capacity(&hash_bucket));
printf("hash table size: %zu\n", get_hash_bucket_size(&hash_bucket));
printf("\nhash bucket destroy\n");
hash_bucket_destroy(&hash_bucket);
printf("hash table capacity: %zu\n", get_hash_bucket_capacity(&hash_bucket));
printf("hash table size: %zu\n", get_hash_bucket_size(&hash_bucket));
}
int main(void)
{
test();
return 0;
}