用C語言實現一個簡單實用的單向鏈表list,具有一定的實際意義。尤其我們不想使用STL裡面的list<...>類的時候。我實現的這個list,結點存儲任何調用者分配的任意類型的數據(void*)。這個list適用於一些簡單的場合,消耗極少的資源。
頭文件:
/*
* list.h
* Generic sequential linked list node structure -- can hold any type data.
* cheungmine
* Sep. 22, 2007. All rights reserved.
*/
#ifndef LIST_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_t size; /* count of nodes */
listnode_t *head;
listnode_t *tail;
}list_t, *list_p;
/* A prototype of callbacked function called by list_destroy(), NULL for no use. */
typedef void(*pfcb_list_node_free)(listnode_t* node);
/* An example of free node data function implemented by callee:
void my_list_node_free(listnode_t *node)
{
free(node->data);
}
*/
/* Appends a node to a list */
extern void
list_append_node(list_t *in_list, listnode_t *in_node);
/* Removes the first node from a list and returns it */
extern listnode_t*
list_remove_head(list_t *in_list);
/* Removes all nodes but for list itself */
extern void
list_remove_all(list_t *in_list, pfcb_list_node_free pfunc /* NULL for no use or a key node */);
/* Returns a copy of a list_t from heap */
extern list_t*
list_copy(list_t in_list);
/* Concatenates two lists into first list. NOT freeing the second */
extern void
list_concat(list_t *first, list_t *second);
/* Allocates a new listnode_t from heap. NO memory allocated for input node_data */
extern listnode_t*
list_node_create(void* node_data);
/* Allocates a new listnode_t with a key node type */
extern listnode_t*
list_key_create(long node_key);
/* Allocates a empty list_t from heap */
extern list_t*
list_create();
/* Frees in_list's all nodes and destroys in_list from heap.
* the callee is responsible for freeing node data.
* the node freed-function(pfunc) is called by list_destroy.
*/
extern void
list_destroy(list_t *in_list, pfcb_list_node_free pfunc /* NULL for no use or a key node */);
/* Gets count of nodes in the list */
extern size_t
list_size(const list_t* in_list);
/* Gets node by index 0-based. 0 is head */
extern listnode_t*
list_node_at(const list_t* in_list, int index);
#endif /* LIST_H_INCLUDED */
實現文件:
/*
* list.c
* Generic linked list implementation.
* cheungmine
* Sep. 22, 2007. All rights reserved.
*/
#include "list.h"
/* Appends a node to a list */
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++;
}
/* Removes the first node from a list and returns it */
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;
}
/* Removes all nodes but for list itself */
void
list_remove_all(list_t *in_list, pfcb_list_node_free pf)
{
listnode_t *node;
while((node = list_remove_head(in_list))){
if (pf) (*pf)(node);
free(node);
}
assert (in_list->size==0);
}
/* Returns a copy of a list_t from heap */
list_t*
list_copy(list_t list)
{
list_t *newlist = (list_t*)malloc (sizeof(list_t));
*newlist = list;
return newlist;
}
/* Concatenates two lists into first list */
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;
}
/* Allocates a new listnode_t from heap */
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;
}
/* Allocates a empty list_t from heap */
list_t*
list_create()
{
list_t *list = (list_t*)malloc (sizeof(list_t));
list->size = 0;
list->head = list->tail = NULL;
return list;
}
/* Frees a empty list_t from heap */
void
list_destroy(list_t *in_list, pfcb_list_node_free pf)
{
list_remove_all(in_list, pf);
free(in_list);
}
/* Gets count of nodes in the list */
size_t
list_size(const list_t* in_list)
{
return in_list->size;
}
/* Gets node by index 0-based. 0 is head */
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-15 Last created by cheungmine.
All rights reserved by cheungmine.
*/
#ifndef UNISTD_H__
#define UNISTD_H__
/* Standard C header files included */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/*============================================================================*/
typedef unsigned char uchar, byte, BYTE;
typedef unsigned short uint16, word_t, ushort;
typedef unsigned __int32 uint, uint32, dword_t, size_t;
typedef unsigned long ulong;
typedef __int16 int16;
typedef __int32 int32;
typedef __int64 int64, longlong;
typedef long lresult;
typedef unsigned __int64 uint64, qword_t, ulonglong;
#ifndef BOOL
typedef int BOOL;
#define TRUE 1
#define FALSE 0
#endif
#ifndef RESULT
#define RESULT lresult
#define _SUCCESS 0
#define _ERROR -1
#endif
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef INOUT
#define INOUT
#endif
#ifndef OPTIONAL
#define OPTIONAL
#endif
#define SIZE_BYTE 1
#define SIZE_ACHAR 1
#define SIZE_WCHAR 2
#define SIZE_SHORT 2
#define SIZE_INT 4
#define SIZE_LONG 4
#define SIZE_FLT 4
#define SIZE_DBL 8
#define SIZE_WORD 2
#define SIZE_DWORD 4
#define SIZE_QWORD 8
#define SIZE_LINT 8
#define SIZE_INT64 8
#define SIZE_UUID 16
/*============================================================================*/
#endif /*UNISTD_H__*/
好了。是不是很簡單啊。適合初學者學習,適合喜歡簡單就是生活的人!