一、实现流程:
1.需要一个空链表(即传入链表进入初始化函数)
2.插入操作:
a:头插
b:尾插
3.遍历整个链表进行打印信息或者删除操作
4.删除节点
5.清空整条链表
6.判断链表是否为空
二、源码
1.头文件list.h
#pragma once
#include <stdlib.h>
#ifndef NDBG
#define PRINT(fmt,args...) printf(fmt,args)
#else
#define PRINT(fmt,args...)
#endif
typedef size_t elem_t;
struct node_info {
elem_t data;
struct node_info *next;
};
#define NODE_MALLOC(type) (type *)malloc(sizeof(type))
2.源文件List.c
#include <stdio.h>
#include <stdlib.h>
#define NDBG
#include "list.h"
/*头插*/
void list_add_head(struct node_info **head,
elem_t data)
{
struct node_info *new_node =
NODE_MALLOC(struct node_info);
if (new_node == NULL) {
fprintf(stderr,"Error Mem Malloc\n");
return ;
}else{
new_node->data = data;
}
new_node->next = *head;
*head = new_node;
PRINT("%s %lu\n",__FUNCTION__, (*head)->data);
}
/*尾插*/
void list_add_tail(struct node_info **head,
elem_t data)
{
struct node_info *new_node =
NODE_MALLOC(struct node_info);
if (new_node == NULL) {
fprintf(stderr,"Error Mem Malloc\n");
return ;
}else{
new_node->data = data;
new_node->next = NULL;
}
if (*head != NULL) {
struct node_info *cur = NULL;
/*遍历链表到最后节点*/
for (cur = *head;
cur->next != NULL;
cur = cur->next)
;
cur->next = new_node;
}else{
*head = new_node;
}
}
int list_is_empty(struct node_info **head)
{
return *head == NULL;
}
/*遍历函数*/
void list_for_each(struct node_info **head,
void (*todo)(struct node_info **head,
struct node_info *node))
{
if (list_is_empty(head)) {
fprintf(stderr,"空链表\n");
return ;
}
struct node_info *cur = NULL;
for (cur = *head;
cur != NULL;
cur = cur->next)
{
todo(head, cur);
}
}
void list_for_each_safe(struct node_info **head,
void (*todo)(struct node_info **head,
elem_t data))
{
struct node_info *cur = NULL;
struct node_info *tmp = NULL;
for (cur = *head; cur != NULL; cur = tmp) {
tmp = cur->next;
todo(head, cur->data);
}
}
void list_del(struct node_info **head, elem_t data)
{
struct node_info *cur = *head;
struct node_info *back = *head;
/*删除第一节点*/
if (cur->data == data) {
*head = cur->next;
cur->next = NULL;
free(cur);
}else{
for (cur = (*head)->next, back = *head;
cur != NULL; )
{
if (cur->data == data){
back->next = cur->next;
cur->next = NULL;
free(cur);
cur = back->next;
}else{
back = cur;
cur = cur->next;
}
}
}
}
/*构造函数*/
void list_init(struct node_info **head)
{
*head = NULL;
}
/*希构函数*/
void list_destroy(struct node_info **head)
{
//todo list_del
list_for_each_safe(head,list_del);
*head = NULL;
}
3.Makefile文件
test : test.c list.c
gcc -o $@ $^
.PHONY: clean
clean:
$(RM) *.o test
4.测试代码test.c
#include <stdio.h>
#include "list.h"
void print_node(struct node_info **head, struct node_info *node)
{
printf("%lu ",node->data);
}
int main()
{
struct node_info *head;
list_init(&head);
elem_t s[] = {2,5,7,9,8,3,0,1};
int i;
for (i = 0; i < sizeof s/ sizeof s[0]; ++i) {
list_add_tail(&head, s[i]);
}
list_del(&head, s[7]);
list_for_each(&head, print_node);
printf("\n");
list_del(&head, s[0]);
list_for_each(&head, print_node);
printf("\n");
list_destroy(&head);
if(list_is_empty())
printf("链表为空\n");
else
printf("链表不为空\n");
}
5.运行结果
01slist/04nohead_noloop# ./test
2 5 7 9 8 3 0
5 7 9 8 3 0