用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");
}
相关推荐
k09339 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯17 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue19 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧21 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
EricWang135830 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
测试界的酸菜鱼32 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
我是谁??32 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
晨曦_子画41 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend1 小时前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
希言JY1 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言