has_head_list.h
#ifndef _HAS_HEAD_LIST_H_
#define _HAS_HEAD_LIST_H_
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEBUG(format, ...) \
do { \
printf("[DEBUG][%s:%d][%s:%s]"format, __FUNCTION__, __LINE__, __DATE__, __TIME__, ##__VA_ARGS__); \
} while (0)
#define ERROR(format, ...) \
do { \
printf("[ERROR][%s:%d][%s:%s]"format, __FUNCTION__, __LINE__, __DATE__, __TIME__, ##__VA_ARGS__); \
} while (0)
struct node
{
int data;
struct node *next;
};
//初始化一个链表
void init_list(struct node **head_p);
//创建一个节点
struct node *make_node(int data);
//释放一个节点
void free_node(struct node *node);
//插入一个节点(头)
int insert_node_from_begin(struct node *head, struct node* node);
//插入一个节点(尾)
int insert_node_to_end(struct node *head, struct node* node);
//查找一个节点
struct node *search(struct node *head, int data);
//删除一个节点
int delete_node(struct node *head, struct node *del_node);
//销毁整个链表
void destory_list(struct node **head_p);
//遍历链表
void print_list(struct node *head);
//逆序单向链表
int reverse(struct node *head);
void print_node(struct node *node); //void ()(struct node *)
void add_node(struct node *node);
void for_each(struct node *head, void(*fp)(struct node*));
#endif
has_head_list.c
#include "has_head_list.h"
void init_list(struct node **head_p)
{
struct node *head = NULL;
if (head_p == NULL) {
return;
}
head = (struct node *)malloc(sizeof(struct node));
if (head == NULL) {
return;
}
head->data = -1; //无意义
head->next = NULL;//代表是空链表
*head_p = head;
}
struct node *make_node(int data)
{
struct node *new_node = NULL;
new_node = (struct node *)malloc(sizeof(struct node));
if (new_node == NULL) {
ERROR("new node == NULL\n");
return NULL;
}
new_node->data = data;
new_node->next = NULL;
return new_node;
}
//释放一个节点
void free_node(struct node *node)
{
if (node != NULL) {
free(node);
}
}
//插入一个节点(尾)
int insert_node_to_end(struct node *head, struct node* node)
{
struct node* last_node = NULL;
if (head == NULL || node == NULL) {
return -1;
}
//找到last_node
for (last_node = head; last_node->next != NULL; last_node = last_node->next)
{
}
//让最后一个节点的下一个指针 指向 node就可以了
last_node->next = node;
node->next = NULL;
return 0;
}
//插入一个节点(头)
int insert_node_from_begin(struct node *head, struct node* node)
{
if (head == NULL || node == NULL) {
return -1;
}
//让新节点的下一个的方向 跟head->next一样
node->next = head->next;
head->next = node;
return 0;
}
//销毁整个链表
void destory_list(struct node **head_p)
{
struct node *head = NULL;
struct node *p = NULL;
if (head_p == NULL) {
return;
}
head = *head_p;
//删除所有链表元素
for (p = head->next; p != NULL; ) {
head->next = p->next;
free_node(p);
p = head->next;
}
//删除头结点本身
free_node(head);
*head_p = NULL;
}
//查找一个节点
struct node *search(struct node *head, int data)
{
struct node *p = NULL;
if (head == NULL) {
return NULL;
}
for (p = head->next; p != NULL; p = p->next)
{
if (p->data == data) {
//找到了data与之对应的节点 此时p就是这个节点的地址
return p;
}
}
return NULL;
}
//删除一个节点
int delete_node(struct node *head, struct node *del_node)
{
struct node*p = NULL;
if (head == NULL || del_node == NULL) {
return -1;
}
//由于要通过p能够指向元素的前驱, 所以p应该从head开始遍历, 因为首元素的前驱就是head
for (p = head; p->next != NULL; p = p->next) {
if (p->next == del_node) {
//此时找到了del_node的前驱节点,就是p
p->next = del_node->next;
free_node(del_node);
break;
}
}
return 0;
}
//逆序单向链表
int reverse(struct node *head)
{
struct node *p = NULL;
struct node *p_prev = NULL;//p的前驱节点
struct node *p_next = NULL;//p的后继节点
if (head == NULL) {
//printf("head is NULL %s:%d\n", __FUNCTION__, __LINE__);
ERROR("head is NULL\n");
return -1;
}
//对空链表的处理
if (head->next == NULL) {
return 0;
}
p = head->next;//p一开始应该指向首元素
p_prev = head;//首元素的前驱就是head
while (p != NULL) {
//给出p的后继
p_next = p->next;
//将p的next指向p的前驱
p->next = p_prev;
//让p的前驱 指向p本身,称为下一个p的前驱
p_prev = p;
//p指向p的后继
p = p_next;
}
//将原先的首元素的next 指向null
head->next->next = NULL;
//head->next指向新的首元素 此时就是p_prev
head->next = p_prev;
return 0;
}
//遍历链表
void print_list(struct node *head)
{
struct node * p = NULL;
if (head == NULL) {
return;
}
for (p = head->next; p != NULL; p = p->next)
{
//printf("%d\n", p->data);
DEBUG("%d\n", p->data);
}
}
//打印一个节点
void print_node(struct node *node) //void ()(struct node *)
{
//printf("%d\n", node->data);
DEBUG("%d\n", node->data);
}
//给一个节点的数值自增1
void add_node(struct node *node)
{
node->data += 1;
}
//
void for_each(struct node *head, void(*fp)(struct node*))
{
struct node *p;
for (p = head->next; p != NULL; p = p->next) {
//P 就代表一个节点
fp(p);
}
}
main.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "has_head_list.h"
int main(int argc, char **argv)
{
struct node *head = NULL;
struct node *new_node = NULL;
struct node *del_node = NULL;
int data = 0;
int num = 10;
int i = 0;
//有头链表 head应该有自己的内存空间
init_list(&head); //head->next = NULL;
for (i = 0; i < num; i++) {
new_node = make_node(i + 10);
//insert_node_to_end(head, new_node);
insert_node_from_begin(head, new_node);
}
//遍历
print_list(head);
printf("请输入要删除的节点:");
scanf("%d", &data);
del_node = search(head, data);
if (del_node != NULL) {
delete_node(head, del_node);
}
//printf("%d\n", strlen("abc"));
printf("----\n");
reverse(head);
//print_list(head);
for_each(head, print_node);
for_each(head, add_node);
for_each(head, print_node);
//销毁链表
destory_list(&head);
if (head == NULL) {
printf("销毁链表成功\n");
}
return 0;
}