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

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


    前面已经出过一个单向链表的系列,这里给出双向链表的实现,这一系列的实现与单向链表有很多类似之处,大家可以参考单向链表的系列。
    
    单向链表的系列(一)的链接是:点击打开链接

    双向链表主要就是加上了一个前向指针其他的并没有太多变化,直接进入正题。

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

/*
*****************************************************************************************
*                                       UART Block
*
*                                      (c) Copyright
*                                   All Rights Reserved
*
* Filename :    MyList_Bidirection.h
*
* Function :    双向非循环链表结构定义及操作函数集声明
*
* History  :    1. wangyi  2015-4-19  17:47  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* pPrevNodeAddr;
   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);

// 比较数据元素的函数,相等返回TRUE,否则返回FALSE
C_Bool compare(MyListData ListData1, MyListData ListData2);

#endif

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

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

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

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

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

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

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

你可能感兴趣的:(经典面试题,C++,C)