llist.h
#ifndef __LLIST_H
#define __LLIST_H
#define LLIST_ADD_FORWARD 0
#define LLIST_ADD_BACKWARD 1
typedef void llist_op(void *);
typedef int llist_cmp(const void *, const void *);
struct llist_node_st {
void *data;
struct llist_node_st *prev;
struct llist_node_st *next;
};
typedef struct {
int size;
struct llist_node_st head;
} LLIST;
LLIST *llist_creat(int size);
int llist_add(LLIST *, const void *data, int dir);
void llist_travel(LLIST *, llist_op *op);
void llist_delet(LLIST *, const void *key, llist_cmp *cmp);
void *llist_find(LLIST *, const void *key, llist_cmp *cmp);
void llist_destroy(LLIST *);
#endif
==========================================================
llist.c
#include <stdlib.h>
#include <string.h>
#include "llist.h"
LLIST *llist_creat(int size)
{
LLIST *new;
new = malloc(sizeof(*new));
if(new == NULL) {
return NULL;
}
new->size = size;
new->head.next = new->head.prev = &new->head;
return new;
}
int llist_add(LLIST *ptr, const void *data, int dir)
{
struct llist_node_st *newnode;
newnode = malloc(sizeof(*newnode));
if(newnode == NULL) {
goto malloc_node_err;
}
newnode->data = malloc(ptr->size);
if(newnode->data == NULL) {
goto malloc_data_err;
}
memcpy(newnode->data, data, ptr->size);
//if(dir == LLIST_ADD_FORWARD)
if(dir == LLIST_ADD_BACKWARD) {
newnode->next = ptr->head.next;
newnode->prev = &ptr->head;
} else {
newnode->next = &ptr->head;
newnode->prev = ptr->head.prev;
}
newnode->next->prev = newnode;
newnode->prev->next = newnode;
return 0;
free(newnode->data);
malloc_data_err:
free(newnode);
malloc_node_err:
return -1;
}
void llist_travel(LLIST *ptr, llist_op *op)
{
struct llist_node_st *cur;
for(cur = ptr->head.next; cur != &ptr->head; cur = cur->next) {
op(cur->data);
}
}
void llist_delet(LLIST *ptr, const void *key, llist_cmp *cmp)
{
struct llist_node_st *cur;
for(cur = ptr->head.next; cur != &ptr->head; cur = cur->next) {
if(cmp(key, cur->data) == 0) {
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur->data);
free(cur);
return ;
}
}
}
void *llist_find(LLIST *ptr, const void *key, llist_cmp *cmp)
{
struct llist_node_st *cur;
for(cur = ptr->head.next; cur != &ptr->head; cur = cur->next) {
if(cmp(key, cur->data) == 0) {
return cur->data;
}
}
return NULL;
}
void llist_destroy(LLIST *ptr)
{
struct llist_node_st *cur, *next;
for(cur = ptr->head.next; cur != &ptr->head; cur = next) {
next = cur->next;
free(cur->data);
free(cur);
}
free(ptr);
}
====================================================
main.c
#include <stdio.h>
#include <string.h>
#include "llist.h"
#define NAMESIZE 32
struct score {
int id;
char name[NAMESIZE];
int china;
int math;
int english;
};
static void print_score(void *data)
{
struct score *d = data;
printf("%d %s %d %d %d\n", d->id, d->name, d->china, d->math, d->english);
}
static int name_cmp(const void *key, const void *data)
{
const char *k = key;
const struct score *d = data;
return strcmp(k, d->name);
}
int main(void)
{
struct score tmp, *p;
LLIST *list;
int i;
list = llist_creat(sizeof(struct score));
/* if error */
for(i = 0; i < 9; i++) {
tmp.id = i;
tmp.china = 100 - i;
tmp.math = 100 - i * 2;
tmp.english = 100 - i * 3;
snprintf(tmp.name, NAMESIZE, "student%d", i);
llist_add(list, &tmp, LLIST_ADD_FORWARD);
}
llist_travel(list, print_score);
//The above of code can done llist_creat,llist_add_forward,llist_travel and final print_score
llist_delet(list, "student6", name_cmp);
llist_travel(list, print_score);
//the above of code can done llist_delet,llist_add_backward
p = llist_find(list, "student2", name_cmp);
if(p == NULL) {
printf("Can not find.\n");
} else {
print_score(p);
}
//the above of code can find score.name flags about "stdxxx".
llist_destroy(list);
//destroy linklist.
return 0;
}