从零实现优雅的C语言数据结构库

一、设计哲学与核心原则

在C语言中实现数据结构库,我们需要在性能、可读性和通用性之间找到平衡点。以下是我们的核心设计原则:

1.1 设计原则

  • 类型安全:使用泛型技术,同时避免过度复杂的宏技巧

  • 内存透明:明确所有权,避免隐藏的内存分配

  • 最小API表面:提供必要的操作,保持接口简洁

  • 零依赖:不依赖外部库,可独立使用

1.2 错误处理策略

c

typedef enum { DS_OK = 0, DS_ERR_ALLOC, DS_ERR_EMPTY, DS_ERR_NOT_FOUND, DS_ERR_INVALID, DS_ERR_OUT_OF_RANGE, DS_ERR_CAPACITY } ds_status_t;

二、内存管理基础

2.1 内存分配器接口

c

typedef struct { void* (*malloc)(size_t size); void* (*calloc)(size_t count, size_t size); void* (*realloc)(void* ptr, size_t size); void (*free)(void* ptr); } ds_allocator_t; // 默认使用标准库分配器 static ds_allocator_t default_allocator = { .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };

2.2 内存池实现(可选)

c

typedef struct { char* buffer; size_t size; size_t used; ds_allocator_t* parent_alloc; } ds_memory_pool_t; ds_status_t ds_pool_init(ds_memory_pool_t* pool, size_t size); void* ds_pool_alloc(ds_memory_pool_t* pool, size_t size); void ds_pool_reset(ds_memory_pool_t* pool); void ds_pool_destroy(ds_memory_pool_t* pool);

三、双向链表实现

3.1 链表节点结构

c

// 前向声明 typedef struct ds_list_node ds_list_node_t; struct ds_list_node { void* data; // 数据指针 ds_list_node_t* prev; // 前驱节点 ds_list_node_t* next; // 后继节点 }; // 链表结构 typedef struct { ds_list_node_t* head; // 头节点 ds_list_node_t* tail; // 尾节点 ds_list_node_t* free_list; // 空闲节点链表(对象池) size_t size; // 元素数量 size_t element_size; // 元素大小(0表示void*) ds_allocator_t* allocator; // 内存分配器 void (*destructor)(void*); // 元素析构函数 } ds_list_t;

3.2 链表API设计

c

// 初始化/销毁 ds_status_t ds_list_init(ds_list_t* list, size_t element_size, ds_allocator_t* allocator); ds_status_t ds_list_init_with_dtor(ds_list_t* list, size_t element_size, void (*destructor)(void*), ds_allocator_t* allocator); void ds_list_destroy(ds_list_t* list); // 基础操作 ds_status_t ds_list_push_back(ds_list_t* list, const void* data); ds_status_t ds_list_push_front(ds_list_t* list, const void* data); ds_status_t ds_list_pop_back(ds_list_t* list, void* out_data); ds_status_t ds_list_pop_front(ds_list_t* list, void* out_data); ds_status_t ds_list_insert(ds_list_t* list, size_t index, const void* data); ds_status_t ds_list_remove(ds_list_t* list, size_t index, void* out_data); // 访问操作 ds_status_t ds_list_get(const ds_list_t* list, size_t index, void* out_data); ds_status_t ds_list_set(ds_list_t* list, size_t index, const void* data); // 查询操作 size_t ds_list_size(const ds_list_t* list); bool ds_list_empty(const ds_list_t* list); ds_list_node_t* ds_list_find(const ds_list_t* list, const void* data, int (*compare)(const void*, const void*)); // 遍历操作 typedef void (*ds_list_iter_fn)(void* data, size_t index, void* user_data); void ds_list_foreach(const ds_list_t* list, ds_list_iter_fn func, void* user_data);

3.3 内部实现细节

c

// 从空闲链表中获取节点或创建新节点 static ds_list_node_t* allocate_node(ds_list_t* list) { ds_list_node_t* node = NULL; if (list->free_list) { // 从对象池复用节点 node = list->free_list; list->free_list = node->next; node->next = NULL; node->prev = NULL; } else { // 分配新节点 node = (ds_list_node_t*)list->allocator->malloc(sizeof(ds_list_node_t)); if (!node) return NULL; // 如果需要存储数据而非指针 if (list->element_size > 0) { node->data = list->allocator->malloc(list->element_size); if (!node->data) { list->allocator->free(node); return NULL; } } else { node->data = NULL; } } return node; } // 释放节点到空闲链表 static void free_node(ds_list_t* list, ds_list_node_t* node) { if (!node) return; // 调用析构函数 if (list->destructor && node->data) { list->destructor(node->data); } // 如果是内联数据,释放数据内存 if (list->element_size > 0 && node->data) { list->allocator->free(node->data); } // 将节点加入空闲链表供复用 node->next = list->free_list; node->prev = NULL; list->free_list = node; } // 在指定位置插入节点 static ds_status_t insert_node(ds_list_t* list, ds_list_node_t* pos, ds_list_node_t* node) { if (!list || !node) return DS_ERR_INVALID; if (!list->head) { // 空链表 list->head = list->tail = node; node->prev = node->next = NULL; } else if (pos == list->head) { // 插入到头部 node->next = list->head; node->prev = NULL; list->head->prev = node; list->head = node; } else if (!pos) { // 插入到尾部 node->prev = list->tail; node->next = NULL; list->tail->next = node; list->tail = node; } else { // 插入到中间 node->prev = pos->prev; node->next = pos; pos->prev->next = node; pos->prev = node; } list->size++; return DS_OK; }

四、动态数组实现

4.1 动态数组结构

c

typedef struct { void* data; // 数据数组 size_t size; // 当前元素数量 size_t capacity; // 总容量 size_t element_size; // 单个元素大小 ds_allocator_t* allocator; // 内存分配器 void (*destructor)(void*); // 元素析构函数 } ds_vector_t;

4.2 动态数组API

c

// 初始化/销毁 ds_status_t ds_vector_init(ds_vector_t* vec, size_t element_size, size_t initial_capacity, ds_allocator_t* allocator); void ds_vector_destroy(ds_vector_t* vec); // 容量管理 ds_status_t ds_vector_reserve(ds_vector_t* vec, size_t new_capacity); ds_status_t ds_vector_resize(ds_vector_t* vec, size_t new_size, const void* fill_value); ds_status_t ds_vector_shrink_to_fit(ds_vector_t* vec); // 元素访问 void* ds_vector_at(ds_vector_t* vec, size_t index); const void* ds_vector_const_at(const ds_vector_t* vec, size_t index); void* ds_vector_front(ds_vector_t* vec); void* ds_vector_back(ds_vector_t* vec); // 修改操作 ds_status_t ds_vector_push_back(ds_vector_t* vec, const void* value); ds_status_t ds_vector_pop_back(ds_vector_t* vec, void* out_value); ds_status_t ds_vector_insert(ds_vector_t* vec, size_t index, const void* value); ds_status_t ds_vector_erase(ds_vector_t* vec, size_t index, void* out_value); ds_status_t ds_vector_clear(ds_vector_t* vec); // 信息查询 size_t ds_vector_size(const ds_vector_t* vec); size_t ds_vector_capacity(const ds_vector_t* vec); bool ds_vector_empty(const ds_vector_t* vec);

4.3 动态数组实现细节

c

// 内部增长策略 static const size_t DS_VECTOR_GROWTH_FACTOR = 2; static const size_t DS_VECTOR_MIN_CAPACITY = 16; static ds_status_t ensure_capacity(ds_vector_t* vec, size_t min_capacity) { if (vec->capacity >= min_capacity) { return DS_OK; } size_t new_capacity = vec->capacity * DS_VECTOR_GROWTH_FACTOR; if (new_capacity < min_capacity) { new_capacity = min_capacity; } if (new_capacity < DS_VECTOR_MIN_CAPACITY) { new_capacity = DS_VECTOR_MIN_CAPACITY; } return ds_vector_reserve(vec, new_capacity); } // 插入元素实现 ds_status_t ds_vector_insert(ds_vector_t* vec, size_t index, const void* value) { if (index > vec->size) { return DS_ERR_OUT_OF_RANGE; } ds_status_t status = ensure_capacity(vec, vec->size + 1); if (status != DS_OK) { return status; } // 移动现有元素 if (index < vec->size) { char* data = (char*)vec->data; char* dest = data + (index + 1) * vec->element_size; char* src = data + index * vec->element_size; size_t bytes = (vec->size - index) * vec->element_size; memmove(dest, src, bytes); } // 插入新元素 char* data = (char*)vec->data; char* dest = data + index * vec->element_size; if (value) { memcpy(dest, value, vec->element_size); } else { memset(dest, 0, vec->element_size); } vec->size++; return DS_OK; }

五、哈希表实现

5.1 哈希表设计

c

// 哈希表条目 typedef struct ds_hash_entry { void* key; void* value; size_t hash; // 缓存哈希值 struct ds_hash_entry* next; // 链表法解决冲突 } ds_hash_entry_t; // 哈希函数类型 typedef size_t (*ds_hash_fn)(const void* key); typedef int (*ds_key_compare_fn)(const void* a, const void* b); // 哈希表结构 typedef struct { ds_hash_entry_t** buckets; // 桶数组 size_t bucket_count; // 桶数量 size_t size; // 元素数量 ds_hash_fn hash_func; // 哈希函数 ds_key_compare_fn key_compare; // 键比较函数 void (*key_destructor)(void*); // 键析构函数 void (*value_destructor)(void*);// 值析构函数 ds_allocator_t* allocator; // 内存分配器 float load_factor; // 加载因子阈值 size_t threshold; // 扩容阈值 } ds_hash_table_t;

5.2 内置哈希函数

c

// DJB2哈希算法 static size_t djb2_hash(const void* data, size_t len) { const unsigned char* str = (const unsigned char*)data; size_t hash = 5381; for (size_t i = 0; i < len; i++) { hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + c */ } return hash; } // 字符串哈希函数 size_t ds_hash_string(const void* key) { const char* str = (const char*)key; size_t len = strlen(str); return djb2_hash(str, len); } // 整数哈希函数(Thomas Wang's 32bit mix) size_t ds_hash_int(const void* key) { int k = *(const int*)key; k = (k ^ 61) ^ (k >> 16); k = k + (k << 3); k = k ^ (k >> 4); k = k * 0x27d4eb2d; k = k ^ (k >> 15); return (size_t)k; }

5.3 哈希表API

c

// 初始化/销毁 ds_status_t ds_hash_table_init(ds_hash_table_t* ht, ds_hash_fn hash_func, ds_key_compare_fn key_compare, size_t initial_capacity, ds_allocator_t* allocator); void ds_hash_table_destroy(ds_hash_table_t* ht); // 基本操作 ds_status_t ds_hash_table_put(ds_hash_table_t* ht, void* key, void* value); void* ds_hash_table_get(const ds_hash_table_t* ht, const void* key); bool ds_hash_table_contains(const ds_hash_table_t* ht, const void* key); ds_status_t ds_hash_table_remove(ds_hash_table_t* ht, const void* key, void** out_key, void** out_value); // 容量管理 ds_status_t ds_hash_table_reserve(ds_hash_table_t* ht, size_t capacity); size_t ds_hash_table_size(const ds_hash_table_t* ht); bool ds_hash_table_empty(const ds_hash_table_t* ht); // 遍历 typedef void (*ds_hash_iter_fn)(void* key, void* value, void* user_data); void ds_hash_table_foreach(const ds_hash_table_t* ht, ds_hash_iter_fn func, void* user_data);

5.4 哈希表实现细节

c

// 内部扩容函数 static ds_status_t resize_table(ds_hash_table_t* ht) { size_t new_capacity = ht->bucket_count * 2; ds_hash_entry_t** new_buckets = ht->allocator->calloc( new_capacity, sizeof(ds_hash_entry_t*)); if (!new_buckets) { return DS_ERR_ALLOC; } // 重新哈希所有条目 for (size_t i = 0; i < ht->bucket_count; i++) { ds_hash_entry_t* entry = ht->buckets[i]; while (entry) { ds_hash_entry_t* next = entry->next; // 计算新桶索引 size_t new_index = entry->hash % new_capacity; // 插入到新桶 entry->next = new_buckets[new_index]; new_buckets[new_index] = entry; entry = next; } } // 更新结构 ht->allocator->free(ht->buckets); ht->buckets = new_buckets; ht->bucket_count = new_capacity; ht->threshold = (size_t)(new_capacity * ht->load_factor); return DS_OK; } // 获取条目 ds_hash_entry_t* get_entry(const ds_hash_table_t* ht, const void* key) { size_t hash = ht->hash_func(key); size_t index = hash % ht->bucket_count; ds_hash_entry_t* entry = ht->buckets[index]; while (entry) { if (entry->hash == hash && ht->key_compare(entry->key, key) == 0) { return entry; } entry = entry->next; } return NULL; } // 插入元素 ds_status_t ds_hash_table_put(ds_hash_table_t* ht, void* key, void* value) { // 检查是否需要扩容 if (ht->size >= ht->threshold) { ds_status_t status = resize_table(ht); if (status != DS_OK) { return status; } } size_t hash = ht->hash_func(key); size_t index = hash % ht->bucket_count; // 检查键是否已存在 ds_hash_entry_t* entry = ht->buckets[index]; while (entry) { if (entry->hash == hash && ht->key_compare(entry->key, key) == 0) { // 更新值 if (ht->value_destructor) { ht->value_destructor(entry->value); } entry->value = value; return DS_OK; } entry = entry->next; } // 创建新条目 entry = ht->allocator->malloc(sizeof(ds_hash_entry_t)); if (!entry) { return DS_ERR_ALLOC; } entry->key = key; entry->value = value; entry->hash = hash; entry->next = ht->buckets[index]; ht->buckets[index] = entry; ht->size++; return DS_OK; }

六、红黑树实现

6.1 红黑树节点结构

c

typedef enum { DS_RED, DS_BLACK } ds_color_t; typedef struct ds_rb_node { void* key; void* value; ds_color_t color; struct ds_rb_node* left; struct ds_rb_node* right; struct ds_rb_node* parent; } ds_rb_node_t; typedef struct { ds_rb_node_t* root; size_t size; ds_key_compare_fn compare; void (*key_destructor)(void*); void (*value_destructor)(void*); ds_allocator_t* allocator; ds_rb_node_t* nil; // 哨兵节点 } ds_rb_tree_t;

6.2 红黑树API

c

// 初始化/销毁 ds_status_t ds_rb_tree_init(ds_rb_tree_t* tree, ds_key_compare_fn compare, ds_allocator_t* allocator); void ds_rb_tree_destroy(ds_rb_tree_t* tree); // 基本操作 ds_status_t ds_rb_tree_insert(ds_rb_tree_t* tree, void* key, void* value); void* ds_rb_tree_get(const ds_rb_tree_t* tree, const void* key); bool ds_rb_tree_contains(const ds_rb_tree_t* tree, const void* key); ds_status_t ds_rb_tree_remove(ds_rb_tree_t* tree, const void* key, void** out_key, void** out_value); // 遍历 typedef void (*ds_rb_iter_fn)(void* key, void* value, void* user_data); void ds_rb_tree_inorder(const ds_rb_tree_t* tree, ds_rb_iter_fn func, void* user_data); void ds_rb_tree_preorder(const ds_rb_tree_t* tree, ds_rb_iter_fn func, void* user_data); void ds_rb_tree_postorder(const ds_rb_tree_t* tree, ds_rb_iter_fn func, void* user_data); // 查询 size_t ds_rb_tree_size(const ds_rb_tree_t* tree); bool ds_rb_tree_empty(const ds_rb_tree_t* tree); ds_rb_node_t* ds_rb_tree_minimum(const ds_rb_tree_t* tree); ds_rb_node_t* ds_rb_tree_maximum(const ds_rb_tree_t* tree);

6.3 红黑树旋转操作

c

// 左旋 static void left_rotate(ds_rb_tree_t* tree, ds_rb_node_t* x) { ds_rb_node_t* y = x->right; x->right = y->left; if (y->left != tree->nil) { y->left->parent = x; } y->parent = x->parent; if (x->parent == tree->nil) { tree->root = y; } else if (x == x->parent->left) { x->parent->left = y; } else { x->parent->right = y; } y->left = x; x->parent = y; } // 右旋 static void right_rotate(ds_rb_tree_t* tree, ds_rb_node_t* y) { ds_rb_node_t* x = y->left; y->left = x->right; if (x->right != tree->nil) { x->right->parent = y; } x->parent = y->parent; if (y->parent == tree->nil) { tree->root = x; } else if (y == y->parent->right) { y->parent->right = x; } else { y->parent->left = x; } x->right = y; y->parent = x; } // 插入修复 static void insert_fixup(ds_rb_tree_t* tree, ds_rb_node_t* z) { while (z->parent->color == DS_RED) { if (z->parent == z->parent->parent->left) { ds_rb_node_t* y = z->parent->parent->right; if (y->color == DS_RED) { // Case 1 z->parent->color = DS_BLACK; y->color = DS_BLACK; z->parent->parent->color = DS_RED; z = z->parent->parent; } else { if (z == z->parent->right) { // Case 2 z = z->parent; left_rotate(tree, z); } // Case 3 z->parent->color = DS_BLACK; z->parent->parent->color = DS_RED; right_rotate(tree, z->parent->parent); } } else { // 对称情况 ds_rb_node_t* y = z->parent->parent->left; if (y->color == DS_RED) { z->parent->color = DS_BLACK; y->color = DS_BLACK; z->parent->parent->color = DS_RED; z = z->parent->parent; } else { if (z == z->parent->left) { z = z->parent; right_rotate(tree, z); } z->parent->color = DS_BLACK; z->parent->parent->color = DS_RED; left_rotate(tree, z->parent->parent); } } } tree->root->color = DS_BLACK; }

七、优先队列(二叉堆)实现

7.1 优先队列结构

c

typedef struct { void* data; // 数据数组 size_t size; // 当前大小 size_t capacity; // 容量 size_t element_size; // 元素大小 ds_allocator_t* allocator; // 分配器 int (*compare)(const void*, const void*); // 比较函数 } ds_priority_queue_t;

7.2 优先队列API

c

// 初始化/销毁 ds_status_t ds_pq_init(ds_priority_queue_t* pq, size_t element_size, int (*compare)(const void*, const void*), size_t initial_capacity, ds_allocator_t* allocator); void ds_pq_destroy(ds_priority_queue_t* pq); // 基本操作 ds_status_t ds_pq_push(ds_priority_queue_t* pq, const void* value); ds_status_t ds_pq_pop(ds_priority_queue_t* pq, void* out_value); ds_status_t ds_pq_peek(const ds_priority_queue_t* pq, void* out_value); // 堆属性操作 ds_status_t ds_pq_heapify(ds_priority_queue_t* pq, const void* array, size_t count); ds_status_t ds_pq_merge(ds_priority_queue_t* dest, const ds_priority_queue_t* src); // 查询 size_t ds_pq_size(const ds_priority_queue_t* pq); bool ds_pq_empty(const ds_priority_queue_t* pq);

7.3 堆操作实现

c

// 上浮操作 static void sift_up(ds_priority_queue_t* pq, size_t index) { char* data = (char*)pq->data; while (index > 0) { size_t parent = (index - 1) / 2; void* child_ptr = data + index * pq->element_size; void* parent_ptr = data + parent * pq->element_size; if (pq->compare(child_ptr, parent_ptr) >= 0) { break; } // 交换父子节点 char temp[pq->element_size]; memcpy(temp, child_ptr, pq->element_size); memcpy(child_ptr, parent_ptr, pq->element_size); memcpy(parent_ptr, temp, pq->element_size); index = parent; } } // 下沉操作 static void sift_down(ds_priority_queue_t* pq, size_t index) { char* data = (char*)pq->data; size_t size = pq->size; while (true) { size_t left = 2 * index + 1; size_t right = 2 * index + 2; size_t smallest = index; if (left < size) { void* left_ptr = data + left * pq->element_size; void* smallest_ptr = data + smallest * pq->element_size; if (pq->compare(left_ptr, smallest_ptr) < 0) { smallest = left; } } if (right < size) { void* right_ptr = data + right * pq->element_size; void* smallest_ptr = data + smallest * pq->element_size; if (pq->compare(right_ptr, smallest_ptr) < 0) { smallest = right; } } if (smallest == index) { break; } // 交换节点 void* index_ptr = data + index * pq->element_size; void* smallest_ptr = data + smallest * pq->element_size; char temp[pq->element_size]; memcpy(temp, index_ptr, pq->element_size); memcpy(index_ptr, smallest_ptr, pq->element_size); memcpy(smallest_ptr, temp, pq->element_size); index = smallest; } } // 插入元素 ds_status_t ds_pq_push(ds_priority_queue_t* pq, const void* value) { if (!pq || !value) return DS_ERR_INVALID; // 确保容量 if (pq->size >= pq->capacity) { size_t new_capacity = pq->capacity * 2; if (new_capacity < 16) new_capacity = 16; void* new_data = pq->allocator->realloc(pq->data, new_capacity * pq->element_size); if (!new_data) return DS_ERR_ALLOC; pq->data = new_data; pq->capacity = new_capacity; } // 添加元素到末尾 char* dest = (char*)pq->data + pq->size * pq->element_size; memcpy(dest, value, pq->element_size); pq->size++; // 上浮新元素 sift_up(pq, pq->size - 1); return DS_OK; }

八、通用迭代器设计

8.1 迭代器接口

c

typedef enum { DS_ITER_LIST, DS_ITER_VECTOR, DS_ITER_HASH_TABLE, DS_ITER_RB_TREE } ds_iter_type_t; typedef struct ds_iterator { ds_iter_type_t type; void* container; void* current; size_t index; // 迭代器方法 bool (*has_next)(struct ds_iterator* iter); void* (*next)(struct ds_iterator* iter); void* (*get_key)(struct ds_iterator* iter); void* (*get_value)(struct ds_iterator* iter); void (*reset)(struct ds_iterator* iter); } ds_iterator_t;

8.2 为各数据结构提供迭代器

c

// 链表迭代器 ds_iterator_t ds_list_iter(const ds_list_t* list); // 向量迭代器 ds_iterator_t ds_vector_iter(const ds_vector_t* vec); // 哈希表迭代器 ds_iterator_t ds_hash_table_iter(const ds_hash_table_t* ht); // 红黑树迭代器 ds_iterator_t ds_rb_tree_iter(const ds_rb_tree_t* tree);

8.3 迭代器使用示例

c

// 通用迭代模式 void iterate_example() { ds_list_t list; ds_list_init(&list, sizeof(int), NULL); // 添加一些数据 for (int i = 0; i < 10; i++) { ds_list_push_back(&list, &i); } // 使用迭代器 ds_iterator_t iter = ds_list_iter(&list); while (ds_iter_has_next(&iter)) { int* value = (int*)ds_iter_next(&iter); printf("%d ", *value); } ds_list_destroy(&list); }

九、测试框架与示例

9.1 单元测试宏

c

#define DS_TEST(condition, message) \ do { \ if (!(condition)) { \ fprintf(stderr, "FAIL: %s (%s:%d)\n", \ message, __FILE__, __LINE__); \ return false; \ } \ } while (0) #define DS_TEST_SUITE(name) \ bool test_##name(void) { \ bool result = true; \ printf("Running test suite: " #name "\n"); #define DS_TEST_END \ return result; \ }

9.2 链表测试示例

c

DS_TEST_SUITE(list_basic) ds_list_t list; ds_status_t status; // 测试初始化 status = ds_list_init(&list, sizeof(int), NULL); DS_TEST(status == DS_OK, "List initialization failed"); DS_TEST(ds_list_empty(&list), "New list should be empty"); // 测试插入 int values[] = {1, 2, 3, 4, 5}; for (int i = 0; i < 5; i++) { status = ds_list_push_back(&list, &values[i]); DS_TEST(status == DS_OK, "Push back failed"); } DS_TEST(ds_list_size(&list) == 5, "Size should be 5"); // 测试访问 int value; status = ds_list_get(&list, 2, &value); DS_TEST(status == DS_OK && value == 3, "Get failed"); // 测试删除 status = ds_list_pop_front(&list, &value); DS_TEST(status == DS_OK && value == 1, "Pop front failed"); DS_TEST(ds_list_size(&list) == 4, "Size should be 4 after pop"); // 清理 ds_list_destroy(&list); DS_TEST_END

十、性能优化技巧

10.1 缓存友好设计

c

// 使用连续内存存储小对象 typedef struct { union { void* ptr; char data[sizeof(void*) * 4]; // 小对象内联存储 }; size_t size; } ds_small_object_t;

10.2 内存对齐

c

// 确保数据结构对齐 #define DS_ALIGNMENT 16 static inline size_t align_up(size_t size, size_t alignment) { return (size + alignment - 1) & ~(alignment - 1); } static inline void* allocate_aligned(ds_allocator_t* alloc, size_t size, size_t alignment) { size_t aligned_size = align_up(size + sizeof(void*), alignment); char* ptr = alloc->malloc(aligned_size); if (!ptr) return NULL; void* aligned_ptr = (void*)align_up((size_t)(ptr + sizeof(void*)), alignment); *((void**)((char*)aligned_ptr - sizeof(void*))) = ptr; return aligned_ptr; }

10.3 对象池优化

c

// 线程安全的对象池 typedef struct { void** objects; size_t capacity; size_t size; pthread_mutex_t mutex; } ds_object_pool_t; ds_status_t ds_object_pool_get(ds_object_pool_t* pool, void** obj) { pthread_mutex_lock(&pool->mutex); if (pool->size > 0) { *obj = pool->objects[--pool->size]; pthread_mutex_unlock(&pool->mutex); return DS_OK; } pthread_mutex_unlock(&pool->mutex); return DS_ERR_EMPTY; }

十一、高级特性

11.1 序列化支持

c

typedef struct { void* (*serialize)(const void* data, size_t* out_size); void* (*deserialize)(const void* buffer, size_t size); } ds_serializer_t; ds_status_t ds_list_serialize(const ds_list_t* list, ds_serializer_t* serializer, void** out_buffer, size_t* out_size); ds_status_t ds_list_deserialize(ds_list_t* list, ds_serializer_t* serializer, const void* buffer, size_t size);

11.2 线程安全包装

c

typedef struct { void* container; pthread_rwlock_t lock; } ds_thread_safe_container_t; ds_status_t ds_ts_container_init(ds_thread_safe_container_t* ts_container, void* container, ds_container_type_t type);

十二、使用示例

12.1 完整示例:单词计数器

c

#include "datastructures.h" #include <ctype.h> #include <stdio.h> typedef struct { char* word; int count; } word_count_t; int compare_words(const void* a, const void* b) { return strcmp((const char*)a, (const char*)b); } size_t hash_word(const void* key) { return ds_hash_string(key); } void free_word(void* ptr) { free(ptr); } void word_counter(const char* filename) { ds_hash_table_t word_counts; ds_hash_table_init(&word_counts, hash_word, compare_words, 100, NULL); // 设置析构函数 word_counts.key_destructor = free_word; word_counts.value_destructor = free_word; FILE* file = fopen(filename, "r"); if (!file) { perror("Failed to open file"); return; } char buffer[256]; while (fscanf(file, "%255s", buffer) == 1) { // 转换为小写 for (char* p = buffer; *p; p++) { *p = tolower(*p); } // 清理标点 char* word = buffer; while (*word && !isalpha(*word)) word++; char* end = word + strlen(word) - 1; while (end > word && !isalpha(*end)) *end-- = '\0'; if (strlen(word) == 0) continue; // 检查是否已存在 int* count_ptr = ds_hash_table_get(&word_counts, word); if (count_ptr) { (*count_ptr)++; } else { char* word_copy = strdup(word); int* new_count = malloc(sizeof(int)); *new_count = 1; ds_hash_table_put(&word_counts, word_copy, new_count); } } fclose(file); // 输出结果 printf("Word frequencies:\n"); ds_iterator_t iter = ds_hash_table_iter(&word_counts); while (ds_iter_has_next(&iter)) { char* word = ds_iter_get_key(&iter); int* count = ds_iter_get_value(&iter); printf("%s: %d\n", word, *count); ds_iter_next(&iter); } ds_hash_table_destroy(&word_counts); }

总结

通过以上设计和实现,我们创建了一个完整、优雅且高效的C语言数据结构库。这个库具有以下特点:

  1. 类型安全:通过element_size和类型特定的比较函数

  2. 内存透明:明确的分配和释放策略

  3. 性能优化:对象池、缓存友好设计、内存对齐

  4. 可扩展性:迭代器接口、序列化支持

  5. 健壮性:全面的错误处理和边界检查

这个实现展示了C语言中数据结构设计的最佳实践,既保持了底层控制的能力,又提供了高级的抽象接口。无论是学习数据结构还是在实际项目中使用,这都是一个极佳的起点。

每个数据结构都可以单独使用或组合使用,库的模块化设计使得添加新数据结构或优化现有实现变得简单。通过遵循这些设计原则,我们可以创建出既优雅又高效的C语言代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1168026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

56Gbps I/O接口的电源完整性考量

物联网数据中心已在串行器/解串器&#xff08;SerDes&#xff09;和Interlaken协议中探索56Gbps及以上速率的传输&#xff1b;然而&#xff0c;物联网数据中心提供商通常不会公开其软硬件技术——因为它们属于集成器件制造商&#xff08;IDM&#xff09;&#xff0c;需自主处理…

双云协同,赋能未来

当华为云的海量算力与尖端算法&#xff0c;邂逅华为终端云服务的亿级全场景入口&#xff0c;一场颠覆性的智能体验变革已然降临。这不仅是技术层面的深度融合&#xff0c;更是生态体系的同频共振&#xff0c;为您解锁前所未有的智慧未来新可能。“一朵云”筑基&#xff0c;驱动…

DeepSeek 发布全新论文,一文读懂 Engram!

在大模型的发展历程中&#xff0c;一个长期困扰研究者效率的难题是&#xff1a;模型往往需要消耗昂贵的计算资源去重建那些本可以通过简单查询获得的静态知识。近日&#xff0c;DeepSeek 团队发布重磅论文 Conditional Memory via Scalable Lookup: A New Axis of Sparsity for…

牛批了,免费抠图神器,内置几个大模型

今天给大家推荐一款非常厉害的基于人工智能抠图的软件&#xff0c;功能非常强大&#xff0c;而且免费&#xff0c;有需要的小伙伴可以下载收藏。 Aiarty Image Matting 免费的AI抠图软件 这款AI抠图软件十分强&#xff0c;基于先进的阿尔法抠图技术&#xff0c;可以精准自然的…

YOLOv11+多尺度卷积注意力(MSCA):小目标检测精度飙升20%的实战教程

文章目录 【毕设级项目】YOLOv11+多尺度卷积注意力(MSCA):小目标检测精度飙升20%的实战教程 一、项目核心:什么是MSCA注意力? 二、环境准备:5分钟配置依赖 三、步骤1:编写MSCA注意力模块(MSCA.py) 四、步骤2:注册MSCA模块(修改tasks.py) 五、步骤3:编写YOLOv11+MS…

发票识别神器,值得收藏

今天给大家带来的是一款非常好用的发票PDF文件识别软件&#xff0c;可以合并pdf文档&#xff0c;识别最新的全电票和旧版电子发票&#xff0c;有需要的小伙伴可以下载收藏。 InvCom 发票PDF文件识别工具 这款软件是绿色版&#xff0c;下载后点击蓝色的图标就能打开直接使用了。…

YOLOv11 结合多尺度卷积注意力机制(MSCA):高效提升小目标检测性能实战指南

文章目录 【毕设级项目】YOLOv11+多尺度卷积注意力(MSCA):小目标检测性能飙升实战教程 引读:为什么选这个项目? 一、核心原理:多尺度卷积注意力(MSCA)是什么? 二、环境准备:5分钟搭好开发环境 1. 基础依赖安装 三、模块植入:3步把MSCA加到YOLOv11里 步骤1:编写MSCA…

TCP/IP协议栈深度解析:网络通信基石、优化与安全实践

引言&#xff1a;数字社会的基石在数字时代&#xff0c;每一次点击、每一次数据传输、每一次在线交互的背后&#xff0c;都有一套精密的通信机制在默默工作。这套机制的核心就是TCP/IP协议栈——一个由多层协议构成的复杂系统&#xff0c;它不仅是互联网的"通用语言"…

1688接入API

1688 API 是阿里巴巴旗下 B2B 批发平台的官方开放接口&#xff0c;基于 RESTful 架构与签名认证&#xff0c;以 JSON 格式提供商品、订单、供应链等全链路数据&#xff0c;核心价值是合规高效赋能采购选品、订单履约、库存协同与分销运营&#xff0c;适配批发 / 零售 / 跨境 / …

基于多尺度空洞注意力(MSDA)的YOLOv11改进与视觉识别优化

文章目录 毕设实战:基于多尺度空洞注意力(MSDA)的YOLOv11改进与视觉识别优化 一、技术背景与方案优势 二、环境搭建与依赖准备 2.1 虚拟环境配置 2.2 数据集准备 三、MSDA模块的代码实现 3.1 多尺度空洞注意力(MSDA)核心代码 3.2 嵌入MSDA到YOLOv11的Backbone 四、模型训练…

漫谈人机协同中的人机功能分配

在人机协同的分工逻辑中&#xff0c;“人杂机复”与“人道机术”是两种互补且有深度的视角&#xff0c;分别从任务属性和职能定位两个维度&#xff0c;揭示了人类与机器在协同中的核心优势与边界。两者结合&#xff0c;为人机协同的高效实现提供了完整的理论框架。一、基于任务…

内存去哪儿了?一个让大多数 Gopher 都无法清晰回答的问题

大家好&#xff0c;我是Tony Bai。“我的服务内存又在缓慢增长了&#xff0c;pprof 显示不出明显的泄漏点……内存到底去哪儿了&#xff1f;”这句午夜梦回的拷问&#xff0c;或许是许多 Go 开发者心中最深的恐惧。这一切的根源&#xff0c;可能始于一个你自以为早已掌握的基础…

【分布式系统】05 时间的幻象 —— Lamport 与 Vector Clock 如何重建分布式因果?

大家好&#xff0c;我是Tony Bai。欢迎来到《分布式系统&#xff1a;原理、哲学与实战》微专栏的第五讲。在过去的几讲中&#xff0c;我们已经深入了两种截然不同的复制哲学。无论是主从架构的“权威中心”&#xff0c;还是无主架构的“民主联邦”&#xff0c;我们都反复遇到了…

面向工业场景的高效目标检测系统:基于BiFPN与注意力机制的YOLOv11架构优化研究

文章目录 **面向工业场景的高效目标检测系统:基于BiFPN与注意力机制的YOLOv11架构优化与实现** **第一章:核心技术架构——双向特征金字塔与注意力协同** **第二章:项目环境配置与数据预处理** **第三章:改进模块完整实现** **第四章:完整网络架构配置** **第五章:优化训…

学霸同款8个AI论文软件,自考学生搞定毕业论文!

学霸同款8个AI论文软件&#xff0c;自考学生搞定毕业论文&#xff01; 论文写作的“学霸同款”工具&#xff0c;你值得拥有 在自考学习的过程中&#xff0c;毕业论文往往成为许多学生最头疼的环节。无论是选题困难、资料查找繁琐&#xff0c;还是撰写过程中逻辑不清、语言表达…

我就改了这 3 个 iOS 26.2 设置——结果现在谁再让我回到“以前”,我真的回不去

iPhone 的系统更新大多时候像什么&#xff1f;像你家楼下便利店换了新海报&#xff1a;你路过会看一眼&#xff0c;但很难因此改变人生。 可这次不一样。我把手机升到 iOS 26.2 之后&#xff0c;随手动了 3 个小设置——注意&#xff0c;是“小设置”&#xff0c;不是那种要重装…

美国战争部AI加速战略的核心就是人机环境系统智能

美国战争部近期启动的AI加速战略&#xff0c;表面上是推动军事AI技术的快速部署与领先&#xff0c;但其深层逻辑可归结为以“人机环境系统智能”为核心&#xff0c;通过重构人&#xff08;军事人员&#xff09;、机&#xff08;AI技术&#xff09;、环境&#xff08;任务场景&a…

YOLOv11+多尺度扩张注意力机制(MSDA):突破性实现40%长距离特征提取性能提升

文章目录 【毕设级项目】YOLOv11+多尺度扩张注意力(MSDA):长距离特征捕获能力提升40%的实战教程 一、项目核心:什么是MSDA注意力? 二、环境准备:5分钟配置依赖 三、步骤1:编写MSDA注意力模块(dilateformer.py) 四、步骤2:注册MSDA模块(修改tasks.py) 五、步骤3:编…

DataGen Connector本地造数神器(不用 Kafka 也能把 Pipeline 跑起来)

1、它到底做了什么 Source 并行运行&#xff1a;有多少个 source 并发子任务&#xff0c;就把 Long 的序列切成多少段&#xff08;sub-sequence&#xff09;你提供一个 GeneratorFunction<Long, OUT>&#xff1a;把输入的 index&#xff08;Long&#xff09;映射成任意事…

“棋圣”聂卫平去世 享年74岁

九派新闻01-15 07:58:06记者从中国围棋协会获悉&#xff0c;中国围棋协会名誉主席、“棋圣”聂卫平九段昨晚在北京病逝&#xff0c;享年74岁。聂卫平是上世纪中国围棋振兴的关键人物&#xff0c;在八十年代的中日围棋擂台赛中&#xff0c;他作为主将力挽狂澜&#xff0c;连胜多…