用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");
}
相关推荐
许苑向上29 分钟前
Java八股文(下)
java·开发语言
谏君之31 分钟前
C语言实现的常见算法示例
c语言·算法·排序算法
菜鸟一枚在这34 分钟前
深入解析设计模式之单例模式
开发语言·javascript·单例模式
独孤求败Ace37 分钟前
第44天:Web开发-JavaEE应用&反射机制&类加载器&利用链&成员变量&构造方法&抽象方法
java·开发语言
计算机-秋大田1 小时前
基于Spring Boot的农产品智慧物流系统设计与实现(LW+源码+讲解)
java·开发语言·spring boot·后端·spring·课程设计
matlabgoodboy1 小时前
Matlab代编电气仿真电力电子电机控制自动化新能源微电网储能能量
开发语言·matlab·自动化
曾浩轩1 小时前
51单片机学习之旅——C语言小知识
c语言·学习·51单片机
镰圈量化1 小时前
当电脑上有几个python版本Vscode选择特定版本python
开发语言·vscode·python
背太阳的牧羊人2 小时前
RAG检索中使用一个 长上下文重排序器(Long Context Reorder) 对检索到的文档进行进一步的处理和排序,优化输出顺序
开发语言·人工智能·python·langchain·rag
ITPUB-微风2 小时前
美团MTSQL特性解析:技术深度与应用广度的完美结合
java·服务器·开发语言