设为首页 加入收藏

TOP

使用C语言实现“泛型”链表(一)
2014-02-08 12:43:39 来源: 作者: 【 】 浏览:597
Tags:使用 语言 实现 泛型 链表

  看到这个标题,你可能非常惊讶,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 RemoveFirst(List list);

  //删除链表list的最后一个结点

  int RemoveLast(List list);

     

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言内存泄漏之free 下一篇实现类似ping功能的C源代码

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: