通用双向链表(二)———接口实现
2014-04-08 18:21
676 查看
/*****************************************dlist.c*********************************************/ #include <stdlib.h> #include "dlist.h" #define RETURN_LAST_IF_FAIL 1 typedef struct _DListNode { struct _DListNode* prev; struct _DListNode* next; void* data; }DListNode; struct _DList { DListNode* first; void* data_destroy_ctx; DListDataDestroyFunc data_destroy; }; static void dlist_destroy_data(DList* thiz, void* data) { if(thiz->data_destroy != NULL) { thiz->data_destroy(thiz->data_destroy_ctx, data); } return; } static DListNode* dlist_create_node(DList* thiz, void* data) { DListNode* node = malloc(sizeof(DListNode)); if(node != NULL) { node->prev = NULL; node->next = NULL; node->data = data; } return node; } static void dlist_destroy_node(DList* thiz, DListNode* node) { if(node != NULL) { node->next = NULL; node->prev = NULL; dlist_destroy_data(thiz, node->data); free(node); } return; } DList* dlist_create(DListDataDestroyFunc data_destroy, void* data_destroy_ctx) { DList* thiz = malloc(sizeof(DList)); if(thiz != NULL) { thiz->first = NULL; thiz->data_destroy = data_destroy; thiz->data_destroy_ctx = data_destroy_ctx; } return thiz; } static DListNode* dlist_get_node(DList* thiz, size_t index, int fail_return_last) { DListNode* iter = NULL; return_val_if_fail(thiz != NULL, NULL); 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; } DListRet dlist_insert(DList* thiz, size_t index, void* data) { DListNode* node = NULL; DListNode* cursor = NULL; return_val_if_fail(thiz != NULL, DLIST_RET_INVALID_PARAMS); if((node = dlist_create_node(thiz, data)) == NULL) { return DLIST_RET_OOM; } if(thiz->first == NULL) { thiz->first = node; return DLIST_RET_OK; } cursor = dlist_get_node(thiz, index, RETURN_LAST_IF_FAIL); if(index < dlist_length(thiz)) { if(thiz->first == cursor) { thiz->first = node; } else { cursor->prev->next = node; node->prev = cursor->prev; } node->next = cursor; cursor->prev = node; } else { cursor->next = node; node->prev = cursor; } return DLIST_RET_OK; } DListRet dlist_prepend(DList* thiz, void* data) { return dlist_insert(thiz, 0, data); } DListRet dlist_append(DList* thiz, void* data) { return dlist_insert(thiz, -1, data); } DListRet dlist_delete(DList* thiz, size_t index) { DListNode* cursor = dlist_get_node(thiz, index, 0); return_val_if_fail(cursor != NULL, DLIST_RET_INVALID_PARAMS); if(cursor != NULL) { if(cursor == thiz->first) { thiz->first = cursor->next; } if(cursor->next != NULL) { cursor->next->prev = cursor->prev; } if(cursor->prev != NULL) { cursor->prev->next = cursor->next; } dlist_destroy_node(thiz, cursor); } return DLIST_RET_OK; } DListRet dlist_get_by_index(DList* thiz, size_t index, void** data) { DListNode* cursor = dlist_get_node(thiz, index, 0); return_val_if_fail(cursor != NULL, DLIST_RET_INVALID_PARAMS); if(cursor != NULL) { *data = cursor->data; } return cursor != NULL ? DLIST_RET_OK : DLIST_RET_FAIL; } DListRet dlist_set_by_index(DList* thiz, size_t index, void* data) { DListNode* cursor = dlist_get_node(thiz, index, 0); return_val_if_fail(cursor != NULL, DLIST_RET_INVALID_PARAMS); if(cursor != NULL) { cursor->data = data; } return cursor != NULL ? DLIST_RET_OK : DLIST_RET_FAIL; } size_t dlist_length(DList* thiz) { size_t length = 0; DListNode* iter = NULL; return_val_if_fail(thiz != NULL, 0); iter = thiz->first; while(iter != NULL) { length++; iter = iter->next; } return length; } DListRet dlist_foreach(DList* thiz, DListDataVisitFunc visit, void* ctx) { DListRet ret = DLIST_RET_OK; DListNode* iter = NULL; return_val_if_fail(thiz != NULL && visit != NULL, DLIST_RET_INVALID_PARAMS); iter = thiz->first; while(iter != NULL && ret != DLIST_RET_STOP) { ret = visit(ctx, iter->data); iter = iter->next; } return ret; } int dlist_find(DList* thiz, DListDataCompareFunc cmp, void* ctx) { int i = 0; DListNode* iter = NULL; return_val_if_fail(thiz != NULL && cmp != NULL, -1); iter = thiz->first; while(iter != NULL) { if(cmp(ctx, iter->data) == 0) { break; } i++; iter = iter->next; } return i; } void dlist_destroy(DList* thiz) { DListNode* iter = NULL; DListNode* next = NULL; return_if_fail(thiz != NULL); iter = thiz->first; while(iter != NULL) { next = iter->next; dlist_destroy_node(thiz, iter); iter = next; } thiz->first = NULL; free(thiz); return; }
相关文章推荐
- Http通用短信接口开发经验及具体开发实现
- JAVA通用Dao接口和hibernate的实现
- 基于GoogleMap,Mapabc,51ditu基于GoogleMap,Mapabc,51ditu,VirtualEarth,YahooMap Api接口的Jquery插件的通用实现(含源代码下载)
- 通用权限管理系统多语言开发接口 ,多业务子系统集成实现过程
- JEE数据库基本操作Basedao层通用接口的实现
- JAVA 代理模式之通用接口/继承的实现方式
- 用C#接口实现通用的文本数据序列化(ZT)
- 缓冲通用接口的设计和实现
- C 实现通用Tween缓动动画(3)快捷链式调用接口
- Atitit 通用接口的设计与实现attilax 总结
- 基于各类地图 Api接口的Jquery插件的通用实现(含源代码下载)
- java web项目DAO层通用接口BaseDao与实现类BaseDaoImpl
- 用C#接口实现通用的文本数据序列化
- Atitit 通用接口的设计与实现attilax 总结
- MVC实现通用的增删改查。使用接口(三)学习
- 【Redis】对通用双向链表实现的理解
- 通用类型的两路归并算法实现(二)——面向接口实现通用类型的两路归并
- 嵌入式系统通用驱动程序接口及其实现-I2C主机设备驱动(视频教学时的同步输入文件)
- 通用权限管理实现标准82个接口参考【附源码】
- 怎样实现文件上传的通用接口