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个链表操作,后续会陆续给出所有的实现。最后还会出给测试用例,希望大家发现错误的话给予指正,谢谢。
相关文章推荐
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- 探讨C语言的那些小秘密之断言
- C语言实现BMP转换JPG的方法
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置
- C语言查找数组里数字重复次数的方法
- C语言泛型编程实例教程
- C语言中使用lex统计文本文件字符数
- 在C语言中转换时间的基本方法介绍
- C语言进制转换代码分享