通用链表是一种动态内存分配的数据结构,其中每个节点包含一个指向下一个节点的指针和一个指向任意类型数据的指针。因此,通用链表可以容纳任意类型的数据,这是其与其他数据结构不同的地方。
通用链表的实现可以分为以下几个步骤:
- 定义通用链表节点结构体
typedef struct node {
void* data;
struct node* next;
} node_t;
其中,data指向任意类型的数据,next指向下一个节点。
- 定义通用链表结构体
typedef struct {
node_t* head;
node_t* tail;
int size;
} list_t;
其中,head指向链表头,tail指向链表尾,size为链表节点数。
- 定义通用链表操作函数
- 初始化链表
void list_init(list_t* list) {
list->head = NULL;
list->tail = NULL;
list->size = 0;
}
- 向链表中添加新节点
void list_append(list_t* list, void* data) {
node_t* new_node = (node_t*)malloc(sizeof(node_t));
new_node->data = data;
new_node->next = NULL;
if (list->size == 0) {
list->head = new_node;
list->tail = new_node;
} else {
list->tail->next = new_node;
list->tail = new_node;
}
list->size++;
}
- 从链表中删除节点
void list_remove(list_t* list, node_t* node) {
if (node == list->head) {
list->head = node->next;
} else {
node_t* cur_node = list->head;
while (cur_node->next != node) {
cur_node = cur_node->next;
}
cur_node->next = node->next;
}
if (node == list->tail) {
list->tail = node->next;
}
free(node);
list->size--;
}
- 遍历链表
void list_traverse(list_t* list, void (*callback) (void*)) {
node_t* cur_node = list->head;
while (cur_node != NULL) {
callback(cur_node->data);
cur_node = cur_node->next;
}
}
- 使用通用链表
int main() {
list_t list;
list_init(&list);
int a = 10;
int* ptr_a = &a;
list_append(&list, ptr_a);
float b = 3.14;
float* ptr_b = &b;
list_append(&list, ptr_b);
char c = 'c';
char* ptr_c = &c;
list_append(&list, ptr_c);
list_traverse(&list, print_data);
list_remove(&list, list.head);
list_traverse(&list, print_data);
return 0;
}
void print_data(void* data) {
printf("%c\n", *((char*)data));
}
该代码首先初始化了一个空的链表,然后向其添加了一个整型、一个浮点型和一个字符型数据。随后遍历了链表并打印了每个节点的数据。之后,删除了头节点并重新遍历了链表,打印出了剩余节点的数据。
【最后一个bug】多平台都有更新和发布,大家可以一键三连,关注+星标,不错过精彩内容~