您的位置:首页 > 编程语言 > C语言/C++

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

2015-11-07 21:55 1066 查看

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,否则返回FALSE
C_Bool compare(MyListData ListData1, MyListData ListData2);

#endif


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

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

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

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

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

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

    总之,这里给出了实现的16个链表操作,后续会陆续给出所有的实现。最后还会出给测试用例,希望大家发现错误的话给予指正,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息