C语言实现链表之单向链表(一)头文件

来源:互联网 发布:大势至usb端口 编辑:程序博客网 时间:2024/04/26 11:47

C语言实现链表之单向链表(一)头文件


    链表作为一种十分常见的数据结构,其应用范围也是极广的。书本上以及网络上有很多链表的程序,但是自己用着不习惯,并且有些地方可能考虑的不是很完善,所以我自己写了一些常用数据结构的操作库,在这里分享给大家,希望可以帮助大家理解链表。

    这里不对链表的理论再进行过多分析,主要是程序实现,所以大家可以在有一定的链表理论基础的时候再来看一下这些程序,也许会有很多收获,不止是程序本身的逻辑,还有一些风格和代码形式都可以参考一下。注意,本系列是单向链表!即指针域只有一个后向指针,并且头指针和尾指针并不相连。

    本次设计的链表操作库主要包含三个文件,分别是:MyList_Single.h---头文件、MyList_Single.c---实现文件以及ListTestTop.c---测试文件。本篇文章先给出本次单向链表库的头文件,概览一下基本的结构形式和实现的功能。

/*******************************************************************************************                                       UART Block**                                     (c) Copyright*                                   All Rights Reserved** Filename :    MyList_Single.h** Function :    单向非循环链表结构定义及操作函数集声明** History  :    1. wangyi  2015-4-15  23:00  Version 1.0  creat*******************************************************************************************/#ifndef _MYLIST_#define _MYLIST_// C中的布尔变量定义typedef enum{FALSE, TRUE}C_Bool;// 链表数据定义typedef struct MyListData{    char cName[20];    int  iAge;}MyListData;// 链表结点定义typedef struct MyListNode{          MyListData  sNodeData;   struct MyListNode* pNextNodeAddr;}MyListNode;// 链表操作函数声明/*============================================================================== *   操作  :为链表的结点分配内存,并初始化数据元素*   操作前:pListNode为链表的结点*   操作后:返回分配内存并初始化后的结点,操作失败返回NULL==============================================================================*/MyListNode* MallocMemInitNode(MyListNode* pListNode);/*============================================================================== *   操作  :创建链表*   操作前:pListNode为链表的头结点*   操作后:读取数据,直到遇到年龄为负数为止,成功返回头结点,失败返回NULL==============================================================================*/MyListNode* CreatMyList(MyListNode* pListNode);/*============================================================================== *   操作  :清空链表,释放结点内存,将链表重置为空表*   操作前:ppHeadNode为链表头指针的二级指针*   操作后:(*ppHeadNode)所指链表中的所有结点的内存被释放==============================================================================*/void ClearMyList(MyListNode** ppHeadNode);/*============================================================================== *   操作  :在头结点之前加入一个新结点*   操作前:pHeadNode为链表的头指针,ListData为待加入的结点数据元素*   操作后:数据元素为ListData的结点被加到pHeadNode前面,操作成功返回新的头结点*           操作失败返回NULL==============================================================================*/MyListNode* InsertFirstNode(MyListNode* pHeadNode, MyListData ListData);/*============================================================================== *   操作  :删除头结点*   操作前:ppHeadNode为链表的头指针的二级指针*   操作后:(*ppHeadNode)指向新的头结点,原头结点被删除,所占内存被释放,*           如果链表中只有头结点,则将(*ppHeadNode)置为NULL,操作成功返*           回TRUE,操作失败返回FALSE==============================================================================*/C_Bool DeletFirstNode(MyListNode** ppHeadNode);/*============================================================================== *   操作  :在尾结点之后加入一个新结点*   操作前:pHeadNode为链表的头指针,ListData为待加入的结点数据元素*   操作后:数据元素为ListData的结点被加到尾结点后面,成功返回头结点,否则返回NULL==============================================================================*/MyListNode* InsertTailNode(MyListNode* pHeadNode, MyListData ListData);/*============================================================================== *   操作  :删除尾结点*   操作前:ppHeadNode为链表的头指针的二级指针*   操作后:尾结点被删除,操作成功返回TRUE,操作失败返回FALSE==============================================================================*/C_Bool DeletTailNode(MyListNode** ppHeadNode);/*============================================================================== *   操作  :在任意位置插入结点*   操作前:pHeadNode为链表的头指针,ListData为待加入的结点数据元素*           name为要插入的位置,iAfterBefore为0时表示插入其后,否则插入其前*   操作后:数据元素为ListData的结点被加到对应位置,成功返回头指针,失败返回NULL==============================================================================*/MyListNode* InsertOtherNode(MyListNode* pHeadNode, MyListData ListData,                             char* name, int iAfterBefore);/*============================================================================== *   操作  :删除任意结点*   操作前:ppHeadNode为链表的头指针的二级指针,name为链表中的数据元素关键字*   操作后:结点被删除,操作成功返回TRUE,操作失败返回FALSE==============================================================================*/C_Bool DeletOtherNode(MyListNode** ppHeadNode, char* name);/*============================================================================== *   操作  :对结点的数据元素进行设置*   操作前:pHeadNode为链表的头指针,i为要被更新数据的结点在链表中的位置,*           UpdateData为要输入更新结点的数据元素*   操作后:pHeadNode所指链表中的第i个结点的数据元素被更新,*           成功返回TRUE,失败返回FALSE==============================================================================*/C_Bool SetCurrentNodeData(MyListNode* pHeadNode, int i, MyListData UpdateData);/*============================================================================== *   操作  :获得结点的数据元素*   操作前:pHeadNode为链表的头指针,i为要获取数据的结点在链表中的位置,*           pGetData为数据元素指针*   操作后:pHeadNode所指链表中的第i个结点的数据元素被放到pGetData中*           成功返回TRUE,失败返回FALSE==============================================================================*/C_Bool GetCurrentNodeData(MyListNode* pHeadNode, int i, MyListData* pGetData);/*============================================================================== *   操作  :检查链表是否为空*   操作前:pHeadNode为链表的头指针*   操作后:如果链表为空,则返回TRUE,否则返回FALSE==============================================================================*/C_Bool CheckMyListEmpty(MyListNode* pHeadNode);/*============================================================================== *   操作  :获得链表的长度*   操作前:pHeadNode为链表的头指针*   操作后:返回链表的长度==============================================================================*/int GetMyListLen(MyListNode* pHeadNode);/*============================================================================== *   操作  :获得链表中对应数据元素的结点*   操作前:pHeadNode为链表的头指针,ListData为要查找的数据元素*           (*compare)()为比较函数的函数指针*   操作后:查找结点,成功返回要查找的结点,失败返回NULL==============================================================================*/MyListNode* FindListDataNode(MyListNode* pHeadNode, MyListData ListData,                             C_Bool (*compare)(MyListData, MyListData));/*============================================================================== *   操作  :打印链表中的所有结点的数据元素*   操作前:pHeadNode为链表的头指针*   操作后:打印出所有数据元素==============================================================================*/void PrintfListDataNode(MyListNode* pHeadNode);/*==============================================================================*   操作  :对链表中的数据进行排序,2015年9月17日添加,采用冒泡排序法*   操作前:pHeadNode为链表的头指针*   操作后:返回排序后的头指针==============================================================================*/MyListNode* SortList(MyListNode* pHeadNode);// 比较数据元素的函数,相等返回TRUE,否则返回FALSEC_Bool compare(MyListData ListData1, MyListData ListData2);#endif

    上面的头文件有几点需要说明:

(1)这是本人原创,每个程序的文件头都会有详细地注释,保证版权问题;

(2)头文件的声明中一般都要加上#ifndef...#define...#endif的结构,用来避免头文件被多次包含,从而导致编译出错;

(3)头文件中定义了C中的布尔变量;

(4)结点的数据此处采用一个简单的结构体,用姓名和年龄来表示其数据;

(5)所有操作都会进行常见的错误判断和处理,后续程序会看到;

    总之,这里给出了实现的16个链表操作,后续会陆续给出所有的实现。最后还会出给测试用例,希望大家发现错误的话给予指正,谢谢。
1 0