使用C语言实现“泛型”链表

本文详细介绍了如何使用C语言实现一个泛型链表,涵盖了设计要点和具体实现步骤,包括数据结构的设计、内存管理以及类型转换等关键问题。通过对不同数据类型的支持,实现了通用的链表操作,提高了代码复用性和灵活性。
摘要由CSDN通过智能技术生成
看到这个标题,你可能非常惊讶,C语言也能实现泛型链表?我们知道链表是我们非常常用的数据结构,但是在C中却没有像C++中的STL那样有一个list的模板类,那么我们是否可以用C语言实现一个像STL中的list那样的泛型链表呢?答案是肯定的。下面就以本人的一个用C语言设计的链表为例子,来分析说明一下本人的设计和实现要点,希望能给你一点有用的帮助。

一、所用的链表类型的选择
我们知道,链表也有非常多的类型,包括单链表、单循环链表、双链表、双向循环链表等。在我的设计中,我的链表使用的类型是双向循环链表,并带一个不保存真实数据的头结点。其原因如下:
1)单链表由于不能从后继定位到前驱,在操作时较为不方便
2)双链表虽然能方便找到前驱,但是如果总是在其尾部插入或删除结点,为了定位的方便和操作的统一(所有的删除和插入操作,都跟在中间插入删除结点的操作一样),还要为其增加一个尾结点,并且程序还要保存一个指向这个尾结点的指针,并管理这个指针,从而增加程序的复杂性。而使用带头结点的循环双向链表,就能方便的定位(其上一个元素为链表的最后一个元素,其下一个元素为链表的第0个元素),并使所有的插入和删除的操作统一,因为头结点也是尾结点。注:结点的下标从0开始,头结点不算入下标值。
3)接口的使用与C++中stl中list和泛型算法的使用大致相同。

二、list类型的定义

为了让大家一睹为快,下面就给出这个用C语言实现的“泛型”的定义,再来说明,我这样设计的原因及要点,其定义如下:
其定义在文件list_v2.c中
typedef struct node
{
    //循环双链表的结点结构
    void* data;//数据域指针
    struct node *next;//指向当前结点的下一结点
    struct node *last;//指向当前结点的上一结点
}Node;

struct list
{
    struct node *head;//头指针,指向头结点
    int data_size;//链表对应的数据所占内存的大小
    int length;//链表list的长度
};
其声明在文件list_v2.h中
//泛型循环双链表,带头结点,结点下标从0开始,头结点不计入下标值


//定义结点指针Node*为List类型的迭代器
typedef struct node* Iterator;


//List类型的定义
typedef struct list* List;


//初始化链表,数据域所占内存的大小由data_size给出
int InitList(List *list, int data_size);


//把data的内容插入到链表list的末尾
//assign指定数据data间的赋值方法
Iterator Append(List list, void *data,
                void (*assign)(void*, const void*));


//把data的内容插入到链表的迭代器it_before的前面
//assign指定数据data间的赋值方法
Iterator Insert(List list, void *data, Iterator it_before,
                void (*assign)(void*, const void*));


//把链表A中迭代器it_a指向的结点移动到链表B中迭代器it_b_befroe的前面
Iterator MoveFromAtoB(List A, Iterator it_a,
                      List B, Iterator it_b_before);


//删除链表list中迭代器it指向的结点
int Remove(List list, Iterator it);


//删除链表list的第0个结点,下标从0开始
int Remove
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值