《系统程序员成长计划》学习交流(2)-通用单链表

【更新说明】

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

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值