用C语言实现单链表

接下来,我们将使用C语言实现无头节点的单链表。

头文件:

cpp 复制代码
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

typedef int SLTDateType;

typedef struct SListNode
{
	SLTDateType data;
	struct SListNode* next;
}SListNode;

// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x);
// 单链表打印
void SListPrint(SListNode* plist);
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x);
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x);
// 单链表的尾删
void SListPopBack(SListNode** pplist);
// 单链表头删
void SListPopFront(SListNode** pplist);
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x);
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
void SListInsertAfter(SListNode** pplist, SListNode** pos, SLTDateType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
void SListEraseAfter(SListNode** pplist, SListNode** ppos);

// 在pos的前面插入
void SLTInsert(SListNode** pphead, SListNode** ppos, SLTDateType x);
// 删除pos位置
void SLTErase(SListNode** pplist, SListNode** ppos);
void SLTDestroy(SListNode** pplist);

函数的实现:

cpp 复制代码
#include "SList.h"

// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x)
{
	SListNode* ret = (SListNode*)malloc(sizeof(SListNode));
	if (ret == NULL)
	{
		perror("malloc");
		exit(0);
	}

	ret->data = x;
	ret->next = NULL;

	return ret;
}

// 单链表打印
void SListPrint(SListNode* plist)
{
	if (plist == NULL)
	{
		printf("NULL\n");
		return;
	}

	SListNode* tmp = plist;
	while (tmp)
	{
		printf("%d->", tmp->data);
		tmp = tmp->next;
	}
	printf("NULL\n");
}

// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x)
{
	assert(pplist);

	SListNode* NewNode = BuySListNode(x);

	if (*pplist == NULL)
	{
		*pplist = NewNode;
	}
	else
	{
		//找尾
		SListNode* tmp = *pplist;
		while (tmp->next)
		{
			tmp = tmp->next;
		}

		tmp->next = NewNode;
	}
}

// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x)
{
	assert(pplist);

	SListNode* NewNode = BuySListNode(x);
	SListNode* tmp = *pplist;
	*pplist = NewNode;
	NewNode->next = tmp;
}

// 单链表的尾删
void SListPopBack(SListNode** pplist)
{
	assert(pplist);

	if (*pplist == NULL)
		return;

	SListNode* tmp = *pplist;
	SListNode* prev = NULL;

	if (tmp->next == NULL)
	{
		*pplist = NULL;
		free(tmp);
		return;
	}

	//找尾
	while (tmp->next)
	{
		prev = tmp;
		tmp = tmp->next;
	}
	free(tmp);
	(prev->next) = NULL;
}

// 单链表头删
void SListPopFront(SListNode** pplist)
{
	assert(pplist);
	if (*pplist == NULL)
		return;

	SListNode* old_head = *pplist;
	*pplist = (*pplist)->next;
	free(old_head);
}

// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x)
{
	if (plist == NULL)
		return NULL;

	SListNode* tmp = plist;
	while (tmp != NULL)
	{
		if (tmp->data == x)
			return tmp;

		tmp = tmp->next;	
	}

	return NULL;
}

//销毁链表
void SLTDestroy(SListNode** pplist)
{
	assert(pplist);
	if (*pplist == NULL)
		return;

	int count = 1;
	SListNode* tmp = *pplist;

	while (tmp->next)
	{
		tmp = tmp->next;
		count++;
	}

	while (count--)
	{
		SListPopBack(pplist);
	}
}

// 单链表在pos位置之后插入x
void SListInsertAfter(SListNode** pplist, SListNode** ppos, SLTDateType x)
{
	SListNode* NewNode = BuySListNode(x);

	if ((*ppos == NULL) && (*pplist = NULL))
	{
		SListPushFront(pplist, x);
		return;
	}

	SListNode* tmp = *pplist;
	SListNode* after = *pplist;
	while ((tmp->next) != NULL)
	{
		after = tmp->next;
		if (tmp == *ppos)
		{
			((*ppos)->next) = NewNode;
			NewNode->next = after;
			return;
		}
		tmp = tmp->next;
	}
	if (*ppos == tmp)
	{
		tmp->next = NewNode;
		return;
	}
	perror("The pointer does not exist");
}

// 单链表删除pos位置之后的值
void SListEraseAfter(SListNode** pplist, SListNode** ppos)
{
	if ((*ppos == NULL) && (*pplist = NULL))
		return;
	else if ((*ppos)->next == NULL)
		return;

	SListNode* tmp = *pplist;
	SListNode* after = *pplist;
	SListNode* aafter = *pplist;

	while ((tmp->next) != NULL)
	{
		after = tmp->next;
		aafter = after->next;

		if (tmp == *ppos)
		{
			free(after);
			after = NULL;
			tmp->next = aafter;
			return;
		}
		tmp = tmp->next;
	}
	if (*ppos == tmp)
		return;
	else
		perror("The pointer does not exist");
}

// 在pos的前面插入
void SLTInsert(SListNode** pplist, SListNode** ppos, SLTDateType x)
{
	assert(pplist);

	if (*pplist == *ppos)
	{
		SListPushFront(pplist, x);
		return;
	}

	SListNode* NewNode = BuySListNode(x);

	SListNode* tmp = *pplist;
	SListNode* prev = *pplist;

	while (tmp->next)
	{
		if (tmp == *ppos)
		{
			prev->next = NewNode;
			NewNode->next = tmp;
			return;
		}
		prev = tmp;
		tmp = tmp->next;
	}
	perror("The pointer does not exist");
}

// 删除pos位置
void SLTErase(SListNode** pplist, SListNode** ppos)
{
	if ((*ppos == NULL) || (*pplist == NULL))
	{
		return;
	}
	else if ((*ppos)->next == NULL)
	{
		SListPopBack(pplist);
		return;
	}

	SListNode* tmp = *pplist;
	SListNode* befor = *pplist;
	SListNode* after = *pplist;

	while ((tmp->next) != NULL)
	{
		after = tmp->next;

		if (tmp == *ppos)
		{
			free(tmp);
			tmp = NULL;
			befor->next = after;
			return;
		}
		befor = tmp;
		tmp = tmp->next;
	}
	if (*ppos == tmp)
		return;
	else
		perror("The pointer does not exist");
}
相关推荐
古希腊掌管学习的神13 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师14 分钟前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
就爱学编程22 分钟前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
每天都要学信号1 小时前
Python(第一天)
开发语言·python
TENET信条1 小时前
day53 第十一章:图论part04
开发语言·c#·图论
北国无红豆1 小时前
【CAN总线】STM32的CAN外设
c语言·stm32·嵌入式硬件
生信圆桌1 小时前
【生信圆桌x教程系列】如何安装 seurat V5版本R包,最详细安装手册
开发语言·r语言
IT猿手1 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解TP1-TP10及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·深度学习·算法·机器学习·matlab·多目标算法