C语言实现一个简单的单向链表list
cheungmine
用C语言实现一个简单实用的单向链表list,具有一定的实际意义。尤其我们不想使用STL里面的list<...>类的时候。我实现的这个list,结点存储任何调用者分配的任意类型的数据(void*)。这个list适用于一些简单的场合,消耗极少的资源。
头文件:
/*
*list.h
*Genericsequentiallinkedlistnodestructure--canholdanytypedata.
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/
#ifndefLIST_H_INCLUDED
#define LIST_H_INCLUDED
#include " unistd.h "
typedef struct _listnode_t
{
struct _listnode_t * next;
union{
void * data;
struct _list_t * list;
const char * str;
long key;
};
}listnode_t;
typedef struct _list_t
{
size_tsize; /* countofnodes */
listnode_t * head;
listnode_t * tail;
}list_t, * list_p;
/* Aprototypeofcallbackedfunctioncalledbylist_destroy(),NULLfornouse. */
typedef void ( * pfcb_list_node_free)(listnode_t * node);
/* Anexampleoffreenodedatafunctionimplementedbycallee:
voidmy_list_node_free(listnode_t*node)
{
free(node->data);
}
*/
/* Appendsanodetoalist */
extern void
list_append_node(list_t * in_list,listnode_t * in_node);
/* Removesthefirstnodefromalistandreturnsit */
extern listnode_t *
list_remove_head(list_t * in_list);
/* Removesallnodesbutforlistitself */
extern void
list_remove_all(list_t * in_list,pfcb_list_node_freepfunc /* NULLfornouseorakeynode */ );
/* Returnsacopyofalist_tfromheap */
extern list_t *
list_copy(list_tin_list);
/* Concatenatestwolistsintofirstlist.NOTfreeingthesecond */
extern void
list_concat(list_t * first,list_t * second);
/* Allocatesanewlistnode_tfromheap.NOmemoryallocatedforinputnode_data */
extern listnode_t *
list_node_create( void * node_data);
/* Allocatesanewlistnode_twithakeynodetype */
extern listnode_t *
list_key_create( long node_key);
/* Allocatesaemptylist_tfromheap */
extern list_t *
list_create();
/* Freesin_list'sallnodesanddestroysin_listfromheap.
*thecalleeisresponsibleforfreeingnodedata.
*thenodefreed-function(pfunc)iscalledbylist_destroy.
*/
extern void
list_destroy(list_t * in_list,pfcb_list_node_freepfunc /* NULLfornouseorakeynode */ );
/* Getscountofnodesinthelist */
extern size_t
list_size( const list_t * in_list);
/* Getsnodebyindex0-based.0ishead */
extern listnode_t *
list_node_at( const list_t * in_list, int index);
#endif /*LIST_H_INCLUDED*/
*list.h
*Genericsequentiallinkedlistnodestructure--canholdanytypedata.
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/
#ifndefLIST_H_INCLUDED
#define LIST_H_INCLUDED
#include " unistd.h "
typedef struct _listnode_t
{
struct _listnode_t * next;
union{
void * data;
struct _list_t * list;
const char * str;
long key;
};
}listnode_t;
typedef struct _list_t
{
size_tsize; /* countofnodes */
listnode_t * head;
listnode_t * tail;
}list_t, * list_p;
/* Aprototypeofcallbackedfunctioncalledbylist_destroy(),NULLfornouse. */
typedef void ( * pfcb_list_node_free)(listnode_t * node);
/* Anexampleoffreenodedatafunctionimplementedbycallee:
voidmy_list_node_free(listnode_t*node)
{
free(node->data);
}
*/
/* Appendsanodetoalist */
extern void
list_append_node(list_t * in_list,listnode_t * in_node);
/* Removesthefirstnodefromalistandreturnsit */
extern listnode_t *
list_remove_head(list_t * in_list);
/* Removesallnodesbutforlistitself */
extern void
list_remove_all(list_t * in_list,pfcb_list_node_freepfunc /* NULLfornouseorakeynode */ );
/* Returnsacopyofalist_tfromheap */
extern list_t *
list_copy(list_tin_list);
/* Concatenatestwolistsintofirstlist.NOTfreeingthesecond */
extern void
list_concat(list_t * first,list_t * second);
/* Allocatesanewlistnode_tfromheap.NOmemoryallocatedforinputnode_data */
extern listnode_t *
list_node_create( void * node_data);
/* Allocatesanewlistnode_twithakeynodetype */
extern listnode_t *
list_key_create( long node_key);
/* Allocatesaemptylist_tfromheap */
extern list_t *
list_create();
/* Freesin_list'sallnodesanddestroysin_listfromheap.
*thecalleeisresponsibleforfreeingnodedata.
*thenodefreed-function(pfunc)iscalledbylist_destroy.
*/
extern void
list_destroy(list_t * in_list,pfcb_list_node_freepfunc /* NULLfornouseorakeynode */ );
/* Getscountofnodesinthelist */
extern size_t
list_size( const list_t * in_list);
/* Getsnodebyindex0-based.0ishead */
extern listnode_t *
list_node_at( const list_t * in_list, int index);
#endif /*LIST_H_INCLUDED*/
实现文件:
/*
*list.c
*Genericlinkedlistimplementation.
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/
#include " list.h "
/* Appendsanodetoalist */
void
list_append_node(list_t * in_list,listnode_t * node)
{
node -> next = NULL;
if (in_list -> head)
{
in_list -> tail -> next = node;
in_list -> tail = node;
}
else
in_list -> head = in_list -> tail = node;
in_list -> size ++ ;
}
/* Removesthefirstnodefromalistandreturnsit */
listnode_t *
list_remove_head(list_t * in_list)
{
listnode_t * node = NULL;
if (in_list -> head)
{
node = in_list -> head;
in_list -> head = in_list -> head -> next;
if (in_list -> head == NULL)
in_list -> tail = NULL;
node -> next = NULL;
in_list -> size -- ;
}
assert(in_list -> size >= 0 );
return node;
}
/* Removesallnodesbutforlistitself */
void
list_remove_all(list_t * in_list,pfcb_list_node_freepf)
{
listnode_t * node;
while ((node = list_remove_head(in_list))){
if (pf)( * pf)(node);
free(node);
}
assert(in_list -> size == 0 );
}
/* Returnsacopyofalist_tfromheap */
list_t *
list_copy(list_tlist)
{
list_t * newlist = (list_t * )malloc( sizeof (list_t));
* newlist = list;
return newlist;
}
/* Concatenatestwolistsintofirstlist */
void
list_concat(list_t * first,list_t * second)
{
if (first -> head)
{
if (second -> head)
{
first -> tail -> next = second -> head;
first -> tail = second -> tail;
}
}
else
* first = * second;
second -> head = second -> tail = NULL;
first -> size += second -> size;
}
/* Allocatesanewlistnode_tfromheap */
listnode_t *
list_node_create( void * data)
{
listnode_t * node = (listnode_t * )malloc( sizeof (listnode_t));
node -> next = NULL;
node -> data = data;
return node;
}
listnode_t *
list_key_create( long key)
{
listnode_t * node = (listnode_t * )malloc( sizeof (listnode_t));
node -> next = NULL;
node -> key = key;
return node;
}
/* Allocatesaemptylist_tfromheap */
list_t *
list_create()
{
list_t * list = (list_t * )malloc( sizeof (list_t));
list -> size = 0 ;
list -> head = list -> tail = NULL;
return list;
}
/* Freesaemptylist_tfromheap */
void
list_destroy(list_t * in_list,pfcb_list_node_freepf)
{
list_remove_all(in_list,pf);
free(in_list);
}
/* Getscountofnodesinthelist */
size_t
list_size( const list_t * in_list)
{
return in_list -> size;
}
/* Getsnodebyindex0-based.0ishead */
listnode_t *
list_node_at( const list_t * in_list, int index)
{
int i = 0 ;
listnode_t * node = in_list -> head;
assert(index >= 0 && index < ( int )in_list -> size);
while (i < index)
{
node = node -> next;
i ++ ;
}
return node;
}
*list.c
*Genericlinkedlistimplementation.
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/
#include " list.h "
/* Appendsanodetoalist */
void
list_append_node(list_t * in_list,listnode_t * node)
{
node -> next = NULL;
if (in_list -> head)
{
in_list -> tail -> next = node;
in_list -> tail = node;
}
else
in_list -> head = in_list -> tail = node;
in_list -> size ++ ;
}
/* Removesthefirstnodefromalistandreturnsit */
listnode_t *
list_remove_head(list_t * in_list)
{
listnode_t * node = NULL;
if (in_list -> head)
{
node = in_list -> head;
in_list -> head = in_list -> head -> next;
if (in_list -> head == NULL)
in_list -> tail = NULL;
node -> next = NULL;
in_list -> size -- ;
}
assert(in_list -> size >= 0 );
return node;
}
/* Removesallnodesbutforlistitself */
void
list_remove_all(list_t * in_list,pfcb_list_node_freepf)
{
listnode_t * node;
while ((node = list_remove_head(in_list))){
if (pf)( * pf)(node);
free(node);
}
assert(in_list -> size == 0 );
}
/* Returnsacopyofalist_tfromheap */
list_t *
list_copy(list_tlist)
{
list_t * newlist = (list_t * )malloc( sizeof (list_t));
* newlist = list;
return newlist;
}
/* Concatenatestwolistsintofirstlist */
void
list_concat(list_t * first,list_t * second)
{
if (first -> head)
{
if (second -> head)
{
first -> tail -> next = second -> head;
first -> tail = second -> tail;
}
}
else
* first = * second;
second -> head = second -> tail = NULL;
first -> size += second -> size;
}
/* Allocatesanewlistnode_tfromheap */
listnode_t *
list_node_create( void * data)
{
listnode_t * node = (listnode_t * )malloc( sizeof (listnode_t));
node -> next = NULL;
node -> data = data;
return node;
}
listnode_t *
list_key_create( long key)
{
listnode_t * node = (listnode_t * )malloc( sizeof (listnode_t));
node -> next = NULL;
node -> key = key;
return node;
}
/* Allocatesaemptylist_tfromheap */
list_t *
list_create()
{
list_t * list = (list_t * )malloc( sizeof (list_t));
list -> size = 0 ;
list -> head = list -> tail = NULL;
return list;
}
/* Freesaemptylist_tfromheap */
void
list_destroy(list_t * in_list,pfcb_list_node_freepf)
{
list_remove_all(in_list,pf);
free(in_list);
}
/* Getscountofnodesinthelist */
size_t
list_size( const list_t * in_list)
{
return in_list -> size;
}
/* Getsnodebyindex0-based.0ishead */
listnode_t *
list_node_at( const list_t * in_list, int index)
{
int i = 0 ;
listnode_t * node = in_list -> head;
assert(index >= 0 && index < ( int )in_list -> size);
while (i < index)
{
node = node -> next;
i ++ ;
}
return node;
}
公共头文件:
/*
unistd.h
2008-09-15Lastcreatedbycheungmine.
Allrightsreservedbycheungmine.
*/
#ifndefUNISTD_H__
#define UNISTD_H__
/* StandardCheaderfilesincluded */
#include < stdio.h >
#include < stdlib.h >
#include < string .h >
#include < assert.h >
/* ============================================================================ */
typedefunsigned char uchar, byte ,BYTE;
typedefunsigned short uint16,word_t, ushort ;
typedefunsigned__int32 uint ,uint32,dword_t,size_t;
typedefunsigned long ulong ;
typedef__int16int16;
typedef__int32int32;
typedef__int64int64,longlong;
typedef long lresult;
typedefunsigned__int64uint64,qword_t,ulonglong;
#ifndefBOOL
typedef int BOOL;
#define TRUE1
#define FALSE0
#endif
#ifndefRESULT
#define RESULTlresult
#define _SUCCESS0
#define _ERROR-1
#endif
#ifndefIN
#define IN
#endif
#ifndefOUT
#define OUT
#endif
#ifndefINOUT
#define INOUT
#endif
#ifndefOPTIONAL
#define OPTIONAL
#endif
#define SIZE_BYTE1
#define SIZE_ACHAR1
#define SIZE_WCHAR2
#define SIZE_SHORT2
#define SIZE_INT4
#define SIZE_LONG4
#define SIZE_FLT4
#define SIZE_DBL8
#define SIZE_WORD2
#define SIZE_DWORD4
#define SIZE_QWORD8
#define SIZE_LINT8
#define SIZE_INT648
#define SIZE_UUID16
/* ============================================================================ */
#endif /*UNISTD_H__*/
2008-09-15Lastcreatedbycheungmine.
Allrightsreservedbycheungmine.
*/
#ifndefUNISTD_H__
#define UNISTD_H__
/* StandardCheaderfilesincluded */
#include < stdio.h >
#include < stdlib.h >
#include < string .h >
#include < assert.h >
/* ============================================================================ */
typedefunsigned char uchar, byte ,BYTE;
typedefunsigned short uint16,word_t, ushort ;
typedefunsigned__int32 uint ,uint32,dword_t,size_t;
typedefunsigned long ulong ;
typedef__int16int16;
typedef__int32int32;
typedef__int64int64,longlong;
typedef long lresult;
typedefunsigned__int64uint64,qword_t,ulonglong;
#ifndefBOOL
typedef int BOOL;
#define TRUE1
#define FALSE0
#endif
#ifndefRESULT
#define RESULTlresult
#define _SUCCESS0
#define _ERROR-1
#endif
#ifndefIN
#define IN
#endif
#ifndefOUT
#define OUT
#endif
#ifndefINOUT
#define INOUT
#endif
#ifndefOPTIONAL
#define OPTIONAL
#endif
#define SIZE_BYTE1
#define SIZE_ACHAR1
#define SIZE_WCHAR2
#define SIZE_SHORT2
#define SIZE_INT4
#define SIZE_LONG4
#define SIZE_FLT4
#define SIZE_DBL8
#define SIZE_WORD2
#define SIZE_DWORD4
#define SIZE_QWORD8
#define SIZE_LINT8
#define SIZE_INT648
#define SIZE_UUID16
/* ============================================================================ */
#endif /*UNISTD_H__*/
好了。是不是很简单啊。适合初学者学习,适合喜欢简单就是生活的人!