以库的方式实现的双向循环链表
main.c
#include <stdio.h>
#include "list.h"
#define NAMESIZE 32
typedef struct score_st
{
int id;
char name[NAMESIZE];
int math;
int chinese;
}score;
static void print_s(const void *record)
{
const score *r = record;
printf("学号:%d 姓名:%s 数学:%d 语文:%d\n", r->id, r->name, r->math, r->chinese);
}
static int id_cmp(const void *key, const void *record)
{
const int *k = key;
const score *r = record;
return (*k - r->id);
}
static int name_cmp(const void *key, const void *record)
{
const char *k = key;
const score *r = record;
return strcmp(k, r->name);
}
int main(void)
{
LIST *handler = list_create(sizeof(score));
if (handler == NULL)
exit(1);
score tmp;
for (int i = 0; i < 7; i++)
{
tmp.id = i;
snprintf(tmp.name, NAMESIZE, "stu%d", i);
tmp.math = rand() % 100;
tmp.chinese = rand() % 100;
int ret = list_insert(handler, &tmp, LIST_FORWARD);
if (ret)
exit(1);
}
list_show(handler, print_s);
printf("delete id = 3\n");
int id = 3;
int ret = list_delete(handler, &id, id_cmp);
if (ret)
printf("list_delete id failed\n");
list_show(handler, print_s);
printf("delete name = stu6\n");
const char *name = "stu6";
ret = list_delete(handler, name, name_cmp);
if (ret)
printf("list_delete name failed\n");
list_show(handler, print_s);
printf("find id = 30\n");
int id1 = 30;
struct score *data;
data = list_find(handler, &id1, id_cmp);
if (data == NULL)
printf("Can not find\n");
else
print_s(data);
list_destory(&handler);
return 0;
}
list.c
#include "list.h"
static node *find_(LIST *ptr, const void *key, list_cmp *cmp)
{
node *current;
for (current = ptr->head.next; current != &ptr->head; current = current->next)
{
if (cmp(key, current->data) == 0)
break;
}
return current;
}
LIST *list_create(int initsize)
{
LIST *new = malloc(sizeof(LIST));
if (new == NULL)
return NULL;
new->size = initsize;
new->head.data = NULL;
new->head.pre = &new->head;
new->head.next = &new->head;
return new;
}
int list_insert(LIST *ptr, const void *data, int mode)
{
node *newnode = malloc(sizeof(node));
if (newnode == NULL)
return -1;
newnode->data = malloc(ptr->size);
if (newnode->data == NULL)
return -2;
memcpy(newnode->data, data, ptr->size);
if (mode == LIST_FORWARD)
{
newnode->pre = &ptr->head;
newnode->next = ptr->head.next;
}
else if (mode == LIST_BACKWARD)
{
newnode->pre = ptr->head.pre;
newnode->next = &ptr->head;
}
else
return -3;
newnode->pre->next = newnode;
newnode->next->pre = newnode;
return 0;
}
void list_show(LIST *ptr, list_op *op)
{
node *current = ptr->head.next;
while (current != &ptr->head)
{
op(current->data);
current = current->next;
}
}
int list_delete(LIST *ptr,const void * key,list_cmp * cmp)
{
struct node_st * node = find_(ptr,key,cmp);
if(node == &ptr->head)
return -1;
node->pre->next = node->next;
node->next->pre = node->pre;
free(node->data);
free(node);
return 0;
}
int list_fetch(LIST *ptr,const void * key,list_cmp *cmp,void * data)
{
struct node_st * node = find_(ptr,key,cmp);
if(node == &ptr->head)
return -1;
node->pre->next = node->next;
node->next->pre = node->pre;
if(data != NULL)
memcpy(data,node->data,ptr->size);
free(node->data);
free(node);
return 0;
}
void list_destory(LIST **ptr)
{
node *current,*next;
LIST *p = *ptr;
for (current = p->head.next; current != &p->head; current = next)
{
next = current->next;
free(current->data);
free(current);
}
free(p);
*ptr = NULL;
}
void *list_find(LIST *ptr, void *key, list_cmp * cmp)
{
node *p = find_(ptr, key, cmp);
if(p == &ptr->head)
return NULL;
return find_(ptr,key,cmp)->data;
}
list.h
#ifndef _LIST_H_
#define _LIST_H_
#include <stdlib.h>
#include <string.h>
#define LIST_FORWARD 1
#define LIST_BACKWARD 2
typedef void list_op(const void *);
typedef int list_cmp(const void *, const void *);
typedef struct node_st
{
void *data;
struct node_st *pre;
struct node_st *next;
}node;
typedef struct
{
int size;
node head;
}LIST;
LIST *list_create(int initsize);
int list_insert(LIST *,const void *data,int mode);
void list_show(LIST *, list_op *);
void *list_find(LIST *, void *key, list_cmp *);
int list_delete(LIST *, const void *key, list_cmp *);
int list_fetch(LIST *,const void * key,list_cmp *,void * data);
void list_destory(LIST **);
#endif