用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");
}
相关推荐
jing-ya14 分钟前
day 59 图论part10
java·开发语言·数据结构·算法·图论
C羊驼23 分钟前
C语言学习笔记(十一):数据在内存中的存储
c语言·经验分享·笔记·学习
雾隐潇湘33 分钟前
C++——第三篇 继承与多态
开发语言·c++
Marye_爱吃樱桃35 分钟前
MATLAB R2024b的安装、简单设置——保姆级教程
开发语言·matlab
旺仔.29135 分钟前
Linux系统基础详解(二)
linux·开发语言·网络
阿贵---35 分钟前
分布式系统C++实现
开发语言·c++·算法
不染尘.37 分钟前
最短路径之Bellman-Ford算法
开发语言·数据结构·c++·算法·图论
格林威37 分钟前
工业相机图像采集:Grab Timeout 设置建议——拒绝“假死”与“丢帧”的黄金法则
开发语言·人工智能·数码相机·计算机视觉·c#·机器视觉·工业相机
xiaoye-duck39 分钟前
C++ STL set 系列深度解析:从底层原理、核心接口到实战场景
开发语言·c++·stl
小涛不学习40 分钟前
Java高频面试题(带答案版)
java·开发语言