目前我正在开发一个用于C语言常见数据结构的小型库。这主要是为了学习目的,但我计划在其他项目中使用此库,以查看其功能和问题所在。到目前为止,我对我的哈希和二叉树实现感到满意,但我无法决定链表的设计。
到目前为止,所有已实现的数据结构都使用
关于链表,我已经找到了三种方法:
现在来谈谈问题:哪种方法最为通用?还有其他方法吗?
到目前为止,所有已实现的数据结构都使用
void
指针,并不负责创建或销毁数据,即它们只引用数据。一个设计目标是尽可能地保持它们的通用性,以增加重复使用性。关于链表,我已经找到了三种方法:
专用列表头:该列表具有专用列表头,用作抽象数据类型。
仅节点:与上面的示例类似,但所有函数都在
list_node
上操作。在 GLib 中使用。在有效负载中:将
list_node
结构添加到有效负载数据中,并使用宏计算偏移量以获取有效负载。参见 lists in the linux kernel编辑 使用宏生成带类型的列表:使用宏创建特定类型版本的列表结构和函数。
1 和 2 的示例:
/* list.h */
typedef struct list_t list;
typedef int (*comparator)(const void* a, const void* b);
list* list_new (comparator c);
void list_delete (list* l);
void list_insert_after (list* l, uint32_t index, void* data);
void list_remove (list* l, void* data);
uint32_t list_size (list* l);
/* other functions operating on lists */
/* list.c */
#include "list.h"
typedef struct list_node_t {
struct list_node_t* next;
struct list_node_t* prev;
void* data;
} list_node;
struct list_t {
list_node* begin;
list_node* end;
uint32_t size;
comparator cmp;
}
现在来谈谈问题:哪种方法最为通用?还有其他方法吗?
size_t
来表示index
、size
等,而不是uint32_t
。 - Paul Rvoid *
或宏,则不需要使用offsetof
。(宏允许您创建一个new
函数,它可以进行堆分配,但通用于实际列表类型。) - Chris Lutz#define list_new(name, next, prev) do { name = malloc(sizeof *name); ((node *)name)->next = next; ((node *)name)->prev == prev; } while(0)
- Chris Lutz