C语言通用双向链表的实现--设计的艺术

本文介绍了C语言中实现通用双向链表的设计和优势,包括专用链表和通用链表的特点。通用链表通过DListNode和DList结构体定义,提供了创建、删除、添加、获取节点等操作,并提供了测试示例。
摘要由CSDN通过智能技术生成

 

转载请注明出处:http://blog.csdn.net/ecorefeng

作者:朱克锋

 

专用链表在这里是指该链表的实现和调用耦合在一起,只能被一个调用者使用,而不能单独在其他地方被重用。通用链表则相反,它具有通用性,可以在多处被重复使用。尽管通用链表相对专用链表来说有很多优越之处,不过草率地断定通用链表比专用链表好也是不公正的,因为它们都有自己的优点和适用范围。

    专用链表的优点

  性能更高。专用链表的实现和调用在一起,可以直接访问数据成员,省去了包装函数带来的性能开销,可以提高时间性能。专用链表无需实现完整的接口,只要满足自己的需要就行了,生成的代码更小,因此可以提高空间性能。

  依赖更少。自己实现不用依赖于别人。有时候你要写一个规模不大的跨平台程序,比如想在展讯手机平台和MTK手机平台上运行,虽然有现存的库可用,但你又不想把整个库移植过去,那么实现一个专用链表是不错的选择。

  实现简单。实现专用链表时,不需要考虑在各种复杂应用情况下的特殊要求,也不需要提供完整的接口,所以实现起来比通用链表更为简单。

  通用链表的优点(从全局来看)

  可靠性更高。通用链表的实现要复杂得多,复杂的东西意味着不可靠。但它是可以重复使用的,其存在的问题会随每一次重用而被发现和改正,慢慢地就形成一个可靠的函数库。

  开发效率更高。通用链表的实现要复杂得多,复杂的东西也意味着更高的开发成本。同样因为它是可以重复使用的,开发成本会随每一次重用而降低,从整个项目来看,会大大提高开发效率。
    注:这段话摘自《系统程序员成长计划》

接下来是对通用链表实现的说明:

    先建立通用链表的存储结构:

typedef struct _DListNode
{
    void *data;
    struct _DListNode *prev;
    struct _DListNode *next;
}DListNode;

typedef struct _DList
{
    DListNode *head;
    DListNode *current;
}DList;

接下来定义一个enum来存放程序中函数的返回值,可以不定义

typedef enum _Ret
{
    RET_OK = 1,
    RET_FAULT,
    RET_OOM,
}Ret;

为了使程序更具通用性可以定义一个回调函数原型,用于回调

typedef void*(*VisitFunc)(void *ctx, void* data);

typedef void (*DesFunc)(DList *dlist, int index);

定义一个用于测试的宏

#define return_val_if_fail(p, val)/
    if(!(p)){printf("%s:%d"#p" failed./n",__func__,__LINE__); return val;}

下面定义通用双向链表的基本操作,包括:

DList *dlist_create();
int dlist_len(DList *dlist);
DListNode *dlist_get(DList *dlist, int index);
Ret dlist_delete(DList *dlist, int index);
Ret dlist_add(DList *dlist, int index,  void *data);
//void dlist_print(DList *dlist, void( *print_func)(void* data));
void *dlist_foreach(DList *dlist, VisitFunc visit_func, void *ctx);
Ret dlist_destroy(DList *dlist,DesFunc des_func, int index);
头文件基本定义结束,保存为dlist.h

为了优化一般会在头文件中定义选择编译的宏

#ifndef DLIST_H
#define DLIST_H
。。。
。。。
#endif /*DLIST_H*/
避免重复编译

完整头文件如

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值