单向链表
话不多说,直接上码
头文件
#ifndef _SINGLE_LINKLIST_H_
#define _SINGLE_LINKLIST_H_
#include "stdio.h"
#include "stdlib.h"
//===============================================================================
//S E L F D E F I N I T I O N
//===============================================================================
#define NODE_DATA_SIZE 20
#define TRUE 1
#define FALSE 0
//===============================================================================
//S T R U C T D E F I N I T I O N
//===============================================================================
typedef int bool;
//-------------------------------------------------------------------------------
//节点元素类型
//-------------------------------------------------------------------------------
typedef struct ElemType
{
char data[NODE_DATA_SIZE];
}ElemType;
//-------------------------------------------------------------------------------
//节点数据类型
//是由于Node在末尾端才定义,但在结构体内部便已经被调用,因此在定时时,
//"struct Node *next" , 如果"Node *next"会出现编译错误
//-------------------------------------------------------------------------------
typedef struct Node
{
//char data[NODE_DATA_SIZE];
ElemType elem; //Node element/data area
struct Node *next; //指向下个节点,注意此处申明的写法
}Node, *LinkList;
//===============================================================================
//F U N C A T I O N D E F I N I T I O N
//===============================================================================
typedef void(* ProcessNodeFun)(Node *node); //节点处理函数
typedef bool(*CompareNodeDataFun)(Node *node, ElemType elemData); //节点数据比较函数
//-------------------------------------------------------------------------------
//创建链表并初始化
//-------------------------------------------------------------------------------
LinkList SingleLinkList_Crate(void);
//-------------------------------------------------------------------------------
//链表为空
//-------------------------------------------------------------------------------
bool SingleLinkList_IsEmpty(LinkList List);
//-------------------------------------------------------------------------------
//当前节点是否为链表尾
//-------------------------------------------------------------------------------
bool SingleLinkList_IsLastNode(Node *node);
//-------------------------------------------------------------------------------
//初始化一个节点,并返回指向该节点的指针
//-------------------------------------------------------------------------------
Node *SingleLinkList_InitialNode(ElemType nodeData);
//-------------------------------------------------------------------------------
//在链表尾插入元素
//-------------------------------------------------------------------------------
bool SingleLinkList_AddNodeToTail(LinkList List, Node *node);
//-------------------------------------------------------------------------------
//遍历链表,并处理链表中某个Node的数据
//-------------------------------------------------------------------------------
void SingleLinkList_Traversal(LinkList List, ProcessNodeFun processfun);
//-------------------------------------------------------------------------------
//遍历链表,返回数据匹配的第一个节点
//-------------------------------------------------------------------------------
Node *SingleLinkList_GetNodeByElemData(LinkList List, ElemType elem, CompareNodeDataFun fun);
//-------------------------------------------------------------------------------
//将某个节点插入到某个特定节点的后面
//-------------------------------------------------------------------------------
void SingleLinkList_InsertNodeAfterOnePosition(LinkList List, ElemType elem, Node *positionNode);
//-------------------------------------------------------------------------------
//查找elem节点的上一个节点
//-------------------------------------------------------------------------------
Node *SingleLinkList_FindPreviousNode(LinkList List, ElemType elem);
//-------------------------------------------------------------------------------
//删除某个特定的节点,待删除的节点数据为elem
//-------------------------------------------------------------------------------
void SingleLinkList_DeleteOneNode(LinkList List, ElemType elem);
//-------------------------------------------------------------------------------
//链表测试
//-------------------------------------------------------------------------------
void SingleLinkList_Test(void);
#endif // !_LINKLIST_H_
接口
//===============================================================================
// Single Link List Module
//===============================================================================
//===============================================================================
//I N C L U D E F I L E
//===============================================================================
#include "SingleLinkList.h"
#include "string.h"
#include "stdlib.h"
#include "assert.h"
//===============================================================================
//S T A T I C D E F I N I T I O N
//===============================================================================
//===============================================================================
//S T A T I C V A R I A B L E
//===============================================================================
static ElemType nodeData[5] = {
"This is Node Data 1",
"This is Node Data 2",
"This is Node Data 3",
"This is Node Data 4",
"This is Node Data 5",
};
//===============================================================================
//S T A T I C F U N D E F I N I T I O N
//===============================================================================
static void SingleLinkList_NodePrintf(Node *node);
static bool SingleLinkList_CompareNodeData(Node *node, ElemType elemData);
static void SingleLinkList_InitElemData(ElemType *elem, char *data);
//-------------------------------------------------------------------------------
//SingleLinkList_NodePrintf(Node *node)
//-------------------------------------------------------------------------------
static void SingleLinkList_NodePrintf(Node *node)
{
printf("%s\n", node->elem.data);
return ;
}
//-------------------------------------------------------------------------------
//SingleLinkList_CompareNodeData(Node *node, ElemType elemData)
//-------------------------------------------------------------------------------
static bool SingleLinkList_CompareNodeData(Node *node, ElemType elemData)
{
bool ret = FALSE;
if (strstr(node->elem.data, (char *)elemData.data) != NULL)
{
ret = TRUE;
}
return ret;
}
//-------------------------------------------------------------------------------
//SingleLinkList_InitElemData(ElemType *elem, char *data)
//-------------------------------------------------------------------------------
static void SingleLinkList_InitElemData(ElemType *elem, char *data)
{
strncpy_s(elem->data, NODE_DATA_SIZE, data, strlen(data));
return;
}
//===============================================================================
//G L O B A L F U N
//===============================================================================
//-------------------------------------------------------------------------------
//SingleLinkList_Crate(LinkList List)
//-------------------------------------------------------------------------------
//!brief 创建一个链表,实际是对链表头的初始化。
//! 1.给链表头分配内存空间
//! 2.将链表头的next指针指向NULL
//-------------------------------------------------------------------------------
LinkList SingleLinkList_Crate(void)
{
LinkList List = NULL;
List = (LinkList)malloc(sizeof(Node)); //注意,这里空间大小的计算,要以Node为内容,LinkList只是一个指针,
//使用sizeof(LinkList), 得到的只是一个指针的空间。
if (List != NULL)
{
List->next = NULL; //链表头初始化,使其next指针指向NULL
}
return List;
}
//-------------------------------------------------------------------------------
//链表为空
//-------------------------------------------------------------------------------
bool SingleLinkList_IsEmpty(LinkList List)
{
bool ret = FALSE;
if (List->next == NULL)
{
ret = TRUE;
}
return ret;
}
//-------------------------------------------------------------------------------
//当前节点是否为链表尾
//-------------------------------------------------------------------------------
bool SingleLinkList_IsLastNode(Node *node)
{
bool ret = FALSE;
if (node->next == NULL)
{
ret = TRUE;
}
return ret;
}
//-------------------------------------------------------------------------------
//初始化一个节点,并返回指向该节点的指针
//-------------------------------------------------------------------------------
//!brief
//! 1.创建一个新的节点,
//! 2.输入数据存储到节点的数据区,并将节点的next指针设置为NULL
//! 3.返回节点指针
//-------------------------------------------------------------------------------
Node *SingleLinkList_InitialNode(ElemType inputData)
{
Node *pNode = NULL;
pNode = (Node *)malloc(sizeof(Node));
if (pNode != NULL)
{
strncpy_s(pNode->elem.data, NODE_DATA_SIZE, inputData.data, strlen(inputData.data));
pNode->next = NULL;
}
else
{
pNode = NULL;
}
return pNode;
}
//-------------------------------------------------------------------------------
//在链表尾插入元素
//-------------------------------------------------------------------------------
//!brief
//!param input List,链表指针
//!param input node,指向节点在内存空间的指针
//-------------------------------------------------------------------------------
bool SingleLinkList_AddNodeToTail(LinkList List, Node *node)
{
bool ret = FALSE;
Node *pNode = NULL;
assert(List);
assert(node);
if (List != NULL)
{
if (SingleLinkList_IsEmpty(List))
{
List->next = node;
node->next = NULL;
}
else
{
pNode = List->next; //获取头结点的下一个节点
while (pNode != NULL)
{
if (SingleLinkList_IsLastNode(pNode)) //是否为最后一个节点
{
pNode->next = node; //插入node节点
node->next = NULL;
break;
}
pNode = pNode->next; //更新当前节点
}
}
ret = TRUE;
}
return ret;
}
//-------------------------------------------------------------------------------
//遍历链表,并对链表Node数据处理
//-------------------------------------------------------------------------------
//!param input List, 链表
//!param input processfun,节点数据处理函数指针
//-------------------------------------------------------------------------------
void SingleLinkList_Traversal(LinkList List, ProcessNodeFun processfun)
{
assert(List);
assert(processfun);
Node *pNode = List->next;
while (pNode)
{
processfun(pNode);
pNode = pNode->next;
}
printf("%s","\r\n");
return;
}
//-------------------------------------------------------------------------------
//返回节点数据为data的 Node
//-------------------------------------------------------------------------------
Node *SingleLinkList_GetNodeByElemData(LinkList List, ElemType elem, CompareNodeDataFun fun)
{
Node *pNode = List;
while (!SingleLinkList_IsLastNode(pNode))
{
if (fun(pNode, elem))
{
break;
}
pNode = pNode->next;
}
return pNode;
}
//-------------------------------------------------------------------------------
//将某个元素插入到某个特定节点的后面
//-------------------------------------------------------------------------------
void SingleLinkList_InsertNodeAfterOnePosition(LinkList List, ElemType elem, Node *positionNode)
{
Node *TmpNode = NULL;
TmpNode = SingleLinkList_InitialNode(elem);
if (TmpNode == NULL)
{
return;
}
else
{
TmpNode->next = positionNode->next;
positionNode->next = TmpNode;
return;
}
}
//-------------------------------------------------------------------------------
//查找elem节点的上一个节点
//-------------------------------------------------------------------------------
Node *SingleLinkList_FindPreviousNode(LinkList List, ElemType elem)
{
assert(List);
Node *pNode = List;
//pNode非空且pNode指向下一个元素的elem与输入的elem不等
while ((!SingleLinkList_IsLastNode(pNode)) && (strstr(pNode->next->elem.data, elem.data) == NULL))
{
pNode = pNode->next;
}
return pNode;
}
//-------------------------------------------------------------------------------
//删除某个特定的节点,待删除的节点数据为elem
//-------------------------------------------------------------------------------
void SingleLinkList_DeleteOneNode(LinkList List, ElemType elem)
{
Node *pNode, *tmpNode;
pNode = SingleLinkList_FindPreviousNode(List, elem);
if (!SingleLinkList_IsLastNode(pNode))
{
tmpNode = pNode->next;
pNode->next = tmpNode->next;
free(tmpNode);
}
}
//-------------------------------------------------------------------------------
//链表测试函数
//-------------------------------------------------------------------------------
//!param input List, 链表
//-------------------------------------------------------------------------------
void SingleLinkList_Test(void)
{
LinkList List = SingleLinkList_Crate(); //创建链表
Node *pNode = NULL;
for (int i=0;i<5;i++)
{
pNode = SingleLinkList_InitialNode(nodeData[i]);
SingleLinkList_AddNodeToTail(List, pNode);
}
SingleLinkList_Traversal(List, SingleLinkList_NodePrintf);
ElemType elem;
SingleLinkList_InitElemData(&elem,"This is Node Data 2");
pNode = SingleLinkList_GetNodeByElemData(List, elem, SingleLinkList_CompareNodeData);
ElemType elemTmp;
SingleLinkList_InitElemData(&elemTmp, "This is node 6");
if (pNode != NULL)
{
SingleLinkList_InsertNodeAfterOnePosition(List, elemTmp, pNode);
}
SingleLinkList_Traversal(List, SingleLinkList_NodePrintf);
SingleLinkList_DeleteOneNode(List, elemTmp);
SingleLinkList_Traversal(List, SingleLinkList_NodePrintf);
return;
}