【更新说明】
2012-08-17:修改Makefile
2012-08-13:增加代码下载链接。
2012-04-22:更新了slist.c中的slist_delete函数实现。
【描述】仿照《系统程序员成长计划》通用双链表,写的一个通用单链表。如有错误,欢迎指正。
【代码清单】
slist.h
#ifndef __SLIST_H__
#define __SLIST_H__
#ifdef __cplusplus
extern "C" {
#endif
struct SListNode;
struct _SList;
typedef struct _SList SList;
typedef enum _SListRet
{
SLIST_RET_OK,
SLIST_RET_ERR_CREATE_NODE,
SLIST_RET_FAIL
}SListRet;
typedef SListRet (* SListDataPrintFunc)(void *data);
SList *slist_create(void);
SListRet slist_insert(SList *thiz, size_t index, void *data);
SListRet slist_delete(SList *thiz, size_t index);
SListRet slist_prepend(SList *thiz, void *data);
SListRet slist_append(SList *thiz, void *data);
SListRet slist_set_by_index(SList *thiz, size_t index, void *data);
SListRet slist_get_by_index(SList *thiz, size_t index, void **data);
size_t slist_length(SList *thiz);
SListRet slist_print(SList *thiz, SListDataPrintFunc print);
SListRet slist_destroy(SList *thiz);
#ifdef __cplusplus
}
#endif
#endif
slist.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "slist.h"
typedef struct _SListNode
{
struct _SListNode *next;
void *data;
}SListNode;
struct _SList
{
SListNode *first;
};
static SListNode *slist_node_create(void *data)
{
SListNode *node = (SListNode *)malloc(sizeof(SListNode));
if(node != NULL)
{
node->next = NULL;
node->data = data;
}
return node;
}
static SListNode *slist_node_destroy(SListNode *node)
{
if(node != NULL)
{
node->next = NULL;
free(node);
}
return SLIST_RET_OK;
}
static SListNode *slist_get_node(SList *thiz, size_t index, int fail_return_last)
{
SListNode *iter = thiz->first;
while(iter!=NULL && iter->next!=NULL && index>0)
{
iter = iter->next;
index--;
}
if(!fail_return_last)
{
iter = index>0 ? NULL : iter;
}
return iter;
}
SList *slist_create(void)
{
SList *thiz = malloc(sizeof(SList));
if(thiz != NULL)
{
thiz->first = NULL;
}
return thiz;
}
SListRet slist_insert(SList *thiz, size_t index, void *data)
{
SListNode *cursor = NULL;
SListNode *prev = NULL;
SListNode *node = NULL;
if( (node=slist_node_create(data)) == NULL)
{
return SLIST_RET_ERR_CREATE_NODE;
}
if(thiz->first == NULL)
{
thiz->first = node;
return SLIST_RET_OK;
}
cursor = slist_get_node(thiz, index, 1);
if(index < slist_length(thiz))
{
if(thiz->first == cursor)
{
thiz->first = node;
}
else
{
prev = slist_get_node(thiz, index-1, 1);
prev->next = node;
}
node->next = cursor;
}
else
{
index = slist_length(thiz);
cursor = slist_get_node(thiz, index, 1);
cursor->next = node;
}
return SLIST_RET_OK;
}
SListRet slist_delete(SList *thiz, size_t index)
{
SListNode *cursor = slist_get_node(thiz, index, 0);
SListNode *temp = slist_get_node(thiz, index-1, 0);
if(cursor != NULL)
{
if(cursor == thiz->first)
{
thiz->first = cursor->next;
}
else
{
if(temp != NULL)
{
temp->next = cursor->next;
}
}
}
slist_node_destroy(cursor);
return SLIST_RET_OK;
}
SListRet slist_prepend(SList *thiz, void *data)
{
return slist_insert(thiz, 0, data);
}
SListRet slist_append(SList *thiz, void *data)
{
return slist_insert(thiz, -1, data);
}
SListRet slist_set_by_index(SList *thiz, size_t index, void *data)
{
SListNode *cursor = slist_get_node(thiz, index, 0);
if(cursor != NULL)
{
cursor->data = data;
}
return cursor != NULL ? SLIST_RET_OK : SLIST_RET_FAIL;
}
SListRet slist_get_by_index(SList *thiz, size_t index, void **data)
{
SListNode *cursor = slist_get_node(thiz, index, 0);
if(cursor != NULL)
{
*data = cursor->data;
}
return cursor != NULL ? SLIST_RET_OK :SLIST_RET_FAIL;
}
size_t slist_length(SList *thiz)
{
size_t length = 0;
SListNode *iter = thiz->first;
while(iter != NULL)
{
iter = iter->next;
length++;
}
return length;
}
SListRet slist_print(SList *thiz, SListDataPrintFunc print)
{
SListNode *iter = thiz->first;
while(iter != NULL)
{
print(iter->data);
iter = iter->next;
}
return SLIST_RET_OK;
}
SListRet slist_destroy(SList *thiz)
{
SListNode *iter = thiz->first;
SListNode *next = NULL;
while(iter != NULL)
{
next = iter ->next;
assert(slist_node_destroy(iter)==SLIST_RET_OK);
iter = next;
}
free(thiz);
thiz->first = NULL;
return SLIST_RET_OK;
}
test.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "slist.h"
static SListRet print_int(void *data)
{
printf("%d ",(int)data);
return SLIST_RET_OK;
}
int main(void)
{
int i = 0;
int n = 100;
void **data;
SList *slist = slist_create();
printf("prepend:\n");
for(i = 0; i < 100; i++)
{
assert(slist_prepend(slist,(void *)i) == SLIST_RET_OK);
}
slist_print(slist,print_int);
printf("\nlength:%d\n\n",slist_length(slist));
printf("append:\n");
for(i = 0; i < 100; i++)
{
assert(slist_append(slist,(void *)i) == SLIST_RET_OK);
}
slist_print(slist,print_int);
printf("\nlength:%d\n\n",slist_length(slist));
printf("insert:\n");
for(i = 0; i < 100; i++)
{
assert(slist_insert(slist,2,(void *)i) == SLIST_RET_OK);
}
slist_print(slist,print_int);
printf("\nlength:%d\n\n",slist_length(slist));
printf("insert:\n");
for(i = 0; i < 100; i++)
{
assert(slist_insert(slist,201,(void *)i) == SLIST_RET_OK);
}
slist_print(slist,print_int);
printf("\nlength:%d\n\n",slist_length(slist));
printf("slist_set_by_index:\n");
assert((slist_set_by_index(slist, 4, (void *)4))== SLIST_RET_OK);
printf("index:%d,data:%d\n",4,(void *)4);
slist_print(slist,print_int);
printf("\nslist_get_by_index:\n");
data = (void **)malloc(1*sizeof(int));
assert((slist_get_by_index(slist, 4, &*data))== SLIST_RET_OK);
printf("%d\n\n",*data);
printf("delete:\n");
for(i = 0; i < 5; i++)
{
assert((slist_delete(slist, i))== SLIST_RET_OK);
}
slist_print(slist,print_int);
printf("\nlength:%d\n\n",slist_length(slist));
printf("destory:\n");
assert((slist_destroy(slist))== SLIST_RET_OK);
printf("length:%d\n",slist_length(slist));
return 0;
}
Makefile (改进的版本,2012-08-17)
cc := gcc
target := test
src := slist.c test.c
temp := $(wildcard *~)
$(target):$(src)
$(cc) -g $(src) -o $(target)
clean:
rm $(temp) $(target)
【代码下载 2012-08-13】
http://download.csdn.net/detail/tandesir/4495448
*Makefile有改动(2012-08-17)
欢迎查找错误,不断改进!
转载请标明出处,仅供学习交流,勿用于商业目的
Copyright @ http://blog.csdn.net/tandesir