C语言数据结构之单向链表

这里写自定义目录标题

单向链表

话不多说,直接上码

头文件

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值