c语言之————无头循环双链表

来源:互联网 发布:数据分析论文 编辑:程序博客网 时间:2024/04/27 14:21

本例是用双链表实现的统计学生信息程序

dlist.h

/* * 描述:无头(头节点有数据)循环双链表 * dlist.h * data: * 2014-07-17 * author: * */#pragma once#include <stdio.h>typedef struct _stu{char name[10];int num;int age;}student;struct node_info{student pers;struct node_info *prev;struct node_info *next;};struct list_info{struct node_info *head;struct node_info fake_head;void (*add)(struct list_info *,struct node_info*);void (*add_tail)(struct list_info *,struct node_info*);void (*for_each_safe)(struct list_info *,void(*)(struct list_info *,struct node_info*,void *),void *par);void (*del)(struct list_info *,struct node_info*);};struct list_info *list_init(struct list_info *);void list_destroy(struct list_info *);

dlist.c

/* * dlist.c */#include "dlist.h"/* 链表不为空,且prev和next指向相邻的节点 */static void __list_insert(struct list_info *info,struct node_info *prev,struct node_info *next,struct node_info *new_node){//printf("-----------------%s\n",__func__);new_node->prev = prev;new_node->next = next;prev->next = new_node;next->prev = new_node;//printf("%s--------------\n",__func__);}/* 头插 */static void list_add(struct list_info *info,struct node_info *new_node){//printf("--------------------------%s\n",__func__);/* 头节点为空 */if(!info->head){info->head->next = new_node;new_node->prev = new_node;new_node->next = new_node;}else/* 头节点不为空,把头节点变为第二个节点 */{__list_insert(info, info->head->prev, info->head, new_node);//new_node->prev = info->head->prev;//info->head->prev = new_node;//info->head->prev->next = new_node;//new_node->next = info->head;info->head = new_node;/* 把new_node变为头节点 */}//printf("%s---------------------------------\n",__func__);}/* 尾插 */static void list_add_tail(struct list_info *info,struct node_info *new_node){//printf("---------------------------%s\n",__func__);/* 头节点为空 */if(!info->head){//info->head->next = new_node;info->head = new_node;new_node->prev = new_node;new_node->next = new_node;}else/* 头节点不为空,保持头节点不变 */{__list_insert(info, info->head->prev, info->head, new_node);}//printf("%s---------------------------------\n",__func__);}/* 遍历链表 */static void list_for_each_safe(struct list_info *info,void (*todo)(struct list_info *,struct node_info *,void *), void *par){//printf("----------------------------%s\n",__func__);/* 如果头节点为空,退出遍历 */if (!info->head){return;}struct node_info *cur = info->head;struct node_info *tmp = cur->next;info->add(info, &info->fake_head);/* 添加了一个空节点(fake_head)为头 */for (cur = info->fake_head.next, tmp = cur->next;cur != &info->fake_head;cur = tmp, tmp = tmp->next) {todo(info, cur, par);}info->del(info, &info->fake_head);/* 删除添加的空节点还原链表 *///printf("%s-----------------------------------\n",__func__);}/* 删除节点 */static void list_del(struct list_info *info,struct node_info *node){//printf("----------------------------------%s\n",__func__);/* 假如为头节点 */if(node == info->head){/* 如果链表就一个头节点 */if(info->head->next == info->head)//node->next == node{info->head = NULL;return;}else{info->head = node->next;}}node->next->prev = node->prev;node->prev->next = node->next;node->next = node;node->prev = node;//printf("%s----------------------------------\n",__func__);}struct list_info *list_init(struct list_info *info){info->head = NULL;info->add = list_add;info->add_tail = list_add_tail;info->for_each_safe = list_for_each_safe;info->del = list_del;return info;}static void __delete_node(struct list_info *info,struct node_info *node, void *par){info->del(info, node);}void list_destroy(struct list_info *info){info->for_each_safe(info, __delete_node, NULL);info->head = NULL;}
测试代码

test.c

/* * test.c */#include "dlist.h"int num = 0;static void print_node(struct list_info *info,struct node_info *node,void *par){printf("\t%d\t %s\t %d\t %d\n ", num,node->pers.name,node->pers.age,node->pers.num);num++;}static void del_node(struct list_info *info,struct node_info *node,void* par){student* s = (student*)par;//char s = (char)par;//int t = (int )par;if ( strcmp(s->name , node->pers.name) == 0 && s->age == node->pers.age && s->num == node->pers.num){info->del(info, node);}//if ((student)par == node->pers) {//info->del(info, node);//}}//static void del_node(struct list_info *info,//struct node_info *node,void *par)//{//if (strcmp(((student)par)->name, node->pers.name) == 0 || ((student)par)->age == node->pers.age || ((student)par)->num == node->pers.num) {//info->del(info, node);//}//}int main(){struct list_info list;list_init(&list);struct node_info s[] = {[0] = {"alien",21,9}, {"taike",20,13}, {"jake",31,50},[7] = {"davie",23,10}, {"Jim",22,4}, {"daent",21,11},[6] = {"chag",32,3},};size_t i = 0;for (i = 0; i < sizeof(s) / sizeof(struct node_info); ++i) {list.add_tail(&list, &s[i]);}printf("\t序号\t 姓名\t 年龄\t 学号\n");list.for_each_safe(&list, print_node, NULL);printf("\n");struct node_info wde;wde = s[7];//printf("\t%s\t %d\t %d\t \n",wde.pers.name,wde.pers.age,wde.pers.num);list.for_each_safe(&list, del_node, (void*)&(wde.pers));//list.del(&list,&wde);//list_del(&list,&wde);printf("删除s[7]后的数据\n");printf("\t序号\t 姓名\t 年龄\t 学号\n");num = 0;//list.for_each_safe(&list, print_node, NULL);//printf("\n");list.for_each_safe(&list, print_node, NULL);printf("\n");list_destroy(&list);return 0;}

Makefile

all:testtest:test.o dlist.ogcc -o $@ $^test.o:test.cgcc -c test.cdlist.o:dlist.cgcc -c dlist.cclean:rm *.o test


运行结果:

序号 姓名 年龄 学号0 alien 9 21 1 taike 13 20 2 jake 50 31 3  0 0 4  0 0 5  0 0 6 chag 3 32 7 davie 10 23 8 Jim 4 22 9 daent 11 21 删除s[7]后的数据序号 姓名 年龄 学号0 alien 9 21 1 taike 13 20 2 jake 50 31 3  0 0 4  0 0 5  0 0 6 chag 3 32 7 Jim 4 22 8 daent 11 21 


0 0
原创粉丝点击