C语言实现一个简单的单向链表list
cheungmine
用C语言实现一个简单实用的单向链表list,具有一定的实际意义。尤其我们不想使用STL里面的list<...>类的时候。我实现的这个list,结点存储任何调用者分配的任意类型的数据(void*)。这个list适用于一些简单的场合,消耗极少的资源。
头文件:
/*
*list.h
*Genericsequentiallinkedlistnodestructure--canholdanytypedata.
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/
#ifndefLIST_H_INCLUDED
#defineLIST_H_INCLUDED
#include"unistd.h"
typedefstruct_listnode_t
{
struct_listnode_t*next;
union{
void*data;
struct_list_t*list;
constchar*str;
longkey;
};
}listnode_t;
typedefstruct_list_t
{
size_tsize;/*countofnodes*/
listnode_t*head;
listnode_t*tail;
}list_t,*list_p;
/*Aprototypeofcallbackedfunctioncalledbylist_destroy(),NULLfornouse.*/
typedefvoid(*pfcb_list_node_free)(listnode_t*node);
/*Anexampleoffreenodedatafunctionimplementedbycallee:
voidmy_list_node_free(listnode_t*node)
{
free(node->data);
}
*/
/*Appendsanodetoalist*/
externvoid
list_append_node(list_t*in_list,listnode_t*in_node);
/*Removesthefirstnodefromalistandreturnsit*/
externlistnode_t*
list_remove_head(list_t*in_list);
/*Removesallnodesbutforlistitself*/
externvoid
list_remove_all(list_t*in_list,pfcb_list_node_freepfunc/*NULLfornouseorakeynode*/);
/*Returnsacopyofalist_tfromheap*/
externlist_t*
list_copy(list_tin_list);
/*Concatenatestwolistsintofirstlist.NOTfreeingthesecond*/
externvoid
list_concat(list_t*first,list_t*second);
/*Allocatesanewlistnode_tfromheap.NOmemoryallocatedforinputnode_data*/
externlistnode_t*
list_node_create(void*node_data);
/*Allocatesanewlistnode_twithakeynodetype*/
externlistnode_t*
list_key_create(longnode_key);
/*Allocatesaemptylist_tfromheap*/
externlist_t*
list_create();
/*Freesin_list'sallnodesanddestroysin_listfromheap.
*thecalleeisresponsibleforfreeingnodedata.
*thenodefreed-function(pfunc)iscalledbylist_destroy.
*/
externvoid
list_destroy(list_t*in_list,pfcb_list_node_freepfunc/*NULLfornouseorakeynode*/);
/*Getscountofnodesinthelist*/
externsize_t
list_size(constlist_t*in_list);
/*Getsnodebyindex0-based.0ishead*/
externlistnode_t*
list_node_at(constlist_t*in_list,intindex);
#endif/*LIST_H_INCLUDED*/
*list.h
*Genericsequentiallinkedlistnodestructure--canholdanytypedata.
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/
#ifndefLIST_H_INCLUDED
#defineLIST_H_INCLUDED
#include"unistd.h"
typedefstruct_listnode_t
{
struct_listnode_t*next;
union{
void*data;
struct_list_t*list;
constchar*str;
longkey;
};
}listnode_t;
typedefstruct_list_t
{
size_tsize;/*countofnodes*/
listnode_t*head;
listnode_t*tail;
}list_t,*list_p;
/*Aprototypeofcallbackedfunctioncalledbylist_destroy(),NULLfornouse.*/
typedefvoid(*pfcb_list_node_free)(listnode_t*node);
/*Anexampleoffreenodedatafunctionimplementedbycallee:
voidmy_list_node_free(listnode_t*node)
{
free(node->data);
}
*/
/*Appendsanodetoalist*/
externvoid
list_append_node(list_t*in_list,listnode_t*in_node);
/*Removesthefirstnodefromalistandreturnsit*/
externlistnode_t*
list_remove_head(list_t*in_list);
/*Removesallnodesbutforlistitself*/
externvoid
list_remove_all(list_t*in_list,pfcb_list_node_freepfunc/*NULLfornouseorakeynode*/);
/*Returnsacopyofalist_tfromheap*/
externlist_t*
list_copy(list_tin_list);
/*Concatenatestwolistsintofirstlist.NOTfreeingthesecond*/
externvoid
list_concat(list_t*first,list_t*second);
/*Allocatesanewlistnode_tfromheap.NOmemoryallocatedforinputnode_data*/
externlistnode_t*
list_node_create(void*node_data);
/*Allocatesanewlistnode_twithakeynodetype*/
externlistnode_t*
list_key_create(longnode_key);
/*Allocatesaemptylist_tfromheap*/
externlist_t*
list_create();
/*Freesin_list'sallnodesanddestroysin_listfromheap.
*thecalleeisresponsibleforfreeingnodedata.
*thenodefreed-function(pfunc)iscalledbylist_destroy.
*/
externvoid
list_destroy(list_t*in_list,pfcb_list_node_freepfunc/*NULLfornouseorakeynode*/);
/*Getscountofnodesinthelist*/
externsize_t
list_size(constlist_t*in_list);
/*Getsnodebyindex0-based.0ishead*/
externlistnode_t*
list_node_at(constlist_t*in_list,intindex);
#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);
returnnode;
}
/*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;
returnnewlist;
}
/*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;
returnnode;
}
listnode_t*
list_key_create(longkey)
{
listnode_t*node=(listnode_t*)malloc(sizeof(listnode_t));
node->next=NULL;
node->key=key;
returnnode;
}
/*Allocatesaemptylist_tfromheap*/
list_t*
list_create()
{
list_t*list=(list_t*)malloc(sizeof(list_t));
list->size=0;
list->head=list->tail=NULL;
returnlist;
}
/*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(constlist_t*in_list)
{
returnin_list->size;
}
/*Getsnodebyindex0-based.0ishead*/
listnode_t*
list_node_at(constlist_t*in_list,intindex)
{
inti=0;
listnode_t*node=in_list->head;
assert(index>=0&&index<(int)in_list->size);
while(i<index)
{
node=node->next;
i++;
}
returnnode;
}
*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);
returnnode;
}
/*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;
returnnewlist;
}
/*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;
returnnode;
}
listnode_t*
list_key_create(longkey)
{
listnode_t*node=(listnode_t*)malloc(sizeof(listnode_t));
node->next=NULL;
node->key=key;
returnnode;
}
/*Allocatesaemptylist_tfromheap*/
list_t*
list_create()
{
list_t*list=(list_t*)malloc(sizeof(list_t));
list->size=0;
list->head=list->tail=NULL;
returnlist;
}
/*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(constlist_t*in_list)
{
returnin_list->size;
}
/*Getsnodebyindex0-based.0ishead*/
listnode_t*
list_node_at(constlist_t*in_list,intindex)
{
inti=0;
listnode_t*node=in_list->head;
assert(index>=0&&index<(int)in_list->size);
while(i<index)
{
node=node->next;
i++;
}
returnnode;
}
公共头文件:
/*unistd.h
2008-09-15Lastcreatedbycheungmine.
Allrightsreservedbycheungmine.
*/
#ifndefUNISTD_H__
#defineUNISTD_H__
/*StandardCheaderfilesincluded*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
/*============================================================================*/
typedefunsignedcharuchar,byte,BYTE;
typedefunsignedshortuint16,word_t,ushort;
typedefunsigned__int32uint,uint32,dword_t,size_t;
typedefunsignedlongulong;
typedef__int16int16;
typedef__int32int32;
typedef__int64int64,longlong;
typedeflonglresult;
typedefunsigned__int64uint64,qword_t,ulonglong;
#ifndefBOOL
typedefintBOOL;
#defineTRUE1
#defineFALSE0
#endif
#ifndefRESULT
#defineRESULTlresult
#define_SUCCESS0
#define_ERROR-1
#endif
#ifndefIN
#defineIN
#endif
#ifndefOUT
#defineOUT
#endif
#ifndefINOUT
#defineINOUT
#endif
#ifndefOPTIONAL
#defineOPTIONAL
#endif
#defineSIZE_BYTE1
#defineSIZE_ACHAR1
#defineSIZE_WCHAR2
#defineSIZE_SHORT2
#defineSIZE_INT4
#defineSIZE_LONG4
#defineSIZE_FLT4
#defineSIZE_DBL8
#defineSIZE_WORD2
#defineSIZE_DWORD4
#defineSIZE_QWORD8
#defineSIZE_LINT8
#defineSIZE_INT648
#defineSIZE_UUID16
/*============================================================================*/
#endif/*UNISTD_H__*/
2008-09-15Lastcreatedbycheungmine.
Allrightsreservedbycheungmine.
*/
#ifndefUNISTD_H__
#defineUNISTD_H__
/*StandardCheaderfilesincluded*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
/*============================================================================*/
typedefunsignedcharuchar,byte,BYTE;
typedefunsignedshortuint16,word_t,ushort;
typedefunsigned__int32uint,uint32,dword_t,size_t;
typedefunsignedlongulong;
typedef__int16int16;
typedef__int32int32;
typedef__int64int64,longlong;
typedeflonglresult;
typedefunsigned__int64uint64,qword_t,ulonglong;
#ifndefBOOL
typedefintBOOL;
#defineTRUE1
#defineFALSE0
#endif
#ifndefRESULT
#defineRESULTlresult
#define_SUCCESS0
#define_ERROR-1
#endif
#ifndefIN
#defineIN
#endif
#ifndefOUT
#defineOUT
#endif
#ifndefINOUT
#defineINOUT
#endif
#ifndefOPTIONAL
#defineOPTIONAL
#endif
#defineSIZE_BYTE1
#defineSIZE_ACHAR1
#defineSIZE_WCHAR2
#defineSIZE_SHORT2
#defineSIZE_INT4
#defineSIZE_LONG4
#defineSIZE_FLT4
#defineSIZE_DBL8
#defineSIZE_WORD2
#defineSIZE_DWORD4
#defineSIZE_QWORD8
#defineSIZE_LINT8
#defineSIZE_INT648
#defineSIZE_UUID16
/*============================================================================*/
#endif/*UNISTD_H__*/
好了。是不是很简单啊。适合初学者学习,适合喜欢简单就是生活的人!
本文介绍了一个用C语言实现的简单单向链表,适用于不需要使用STL的情况。该链表可以存储任意类型的数据,并提供了添加、删除等基本操作。
1095

被折叠的 条评论
为什么被折叠?



