以库的方式实现的双向循环链表
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