单链表(纯代码)

SListNode.h

cpp 复制代码
#pragma once
#include <stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLDatetype;
typedef struct SListNode
{
	SLDatetype data;//节点数据
	struct SListNode* next;//指针保存下一个节点的地址
}SLND;

//打印链表
void SLTPrint(SLND* pphead);
//头插
void SLTPushFront(SLND** pphead,SLDatetype x);
//尾插
void SLTPushback(SLND** pphead,SLDatetype x);
//尾删
void SLTPopback(SLND** pphead);
//头删
void SLTPopFront(SLND** pphead);
//查找
SLND* SLFind(SLND* phead, SLDatetype x);
//在指定位置之前插入数据
void SLTInsert(SLND** pphead,SLND*pos,SLDatetype x);
//删除指定节点
void SLTErase(SLND** pphead,SLND*pos);
//在指定位置之后插入数据
void SLTInsertAfter(SLND* pos, SLDatetype x);
//删除指定位置之后节点
void SLTEraseAfter(SLND* pos);
//销毁链表
void SLTDestory(SLND** pphead);

SListNode.c

cpp 复制代码
#include"SListNode.h"
#include<assert.h>
//创建新的节点
SLND* SLTBuyNode(SLDatetype x)
{
	SLND* newnode = (SLND*)malloc(sizeof(SLND));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}
//尾插
void SLTPushback(SLND** pphead,SLDatetype x)
{
	//不能对空指针进行简引用
	assert(pphead);
	//*pphead是指向第一个节点的指针
	//	空链表和非空链表
	SLND* newnode = SLTBuyNode(x);
	//空链表申请过来的节点就是尾节点
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		//找尾
		SLND* patail = *pphead;
			while (patail->next)
			{
				patail = patail->next;
			}
			//此时patail指向的就是尾节点
			patail->next = newnode;
	}
}
//打印链表
void SLTPrint(SLND* phead)
{
	SLND* pcur = phead;
	while (pcur)//pcur!=NULL
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("NULL\n");
}

//头插
void SLTPushFront(SLND** pphead, SLDatetype x)
{
	assert(pphead);
	SLND* newnode = SLTBuyNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}
//尾删
void SLTPopback(SLND** pphead)
{
	//链表不能为空
	assert(pphead);
	//链表只有一个节点
	if ((*pphead)->next == NULL)//->优先级高于*
	{
		free(*pphead);
		*pphead = NULL;
	}
	else//链表有多个节点
	{
		SLND* prev = *pphead;
		SLND* ptail = *pphead;
		while (ptail->next)
		{
			prev = ptail;
			ptail = ptail ->next;
		}
		free(ptail);
		ptail = NULL;
		prev->next = NULL;
	}
}
//头删
void SLTPopFront(SLND** pphead)
{
//链表不能为空
	assert(pphead && *pphead);
	SLND* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

//查找
SLND* SLFind(SLND* phead, SLDatetype x)
{
	SLND* pcur = phead;
	while (pcur)//等价于pcur!=NULL
	{
		if (pcur->data == x)
		{
			printf("找到啦!\n");
			return pcur;
		}
		pcur = pcur->next;
	}
	//pcur==NULL
	printf("没找到。\n");
	return NULL;
}

//在指定位置之前插入数据
void SLTInsert(SLND** pphead, SLND* pos, SLDatetype x)
{
	assert(pphead && *pphead);
	assert(pos);
	SLND* newnode = SLTBuyNode(x);
	//若pos==*pphead;说明是头插
	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLND* prev = *pphead;
		while(prev->next!=pos)
		{
			prev = prev->next;
		}
		newnode->next = pos;
		prev->next = newnode;
	}
}

//在指定位置之后插入数据
void SLTInsertAfter(SLND* pos, SLDatetype x)
{
	assert(pos);
	SLND* newnode = SLTBuyNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

//删除指定节点
void SLTErase(SLND** pphead, SLND* pos)
{
	assert(pphead && *pphead);
	assert(pos);
	//pos是否是头节点
		if (pos == *pphead)
		{
			//头删
			SLTPopFront(pphead);
		}
		else
		{
			SLND* prev = *pphead;
			while (prev->next!=pos)
			{
				prev = prev->next;
			}
			prev->next = pos->next;
			free(pos);
			pos = NULL;
		}
}

//删除指定位置之后节点
void SLTEraseAfter(SLND* pos)
{
	assert(pos && pos->next);
		//不能assert(pos->next&&pos);这样写
		//因为如果pos为NULL,无法对其简引用
		SLND* del = pos->next;
		pos->next = del->next;
		free(del);
	     del = NULL;
}

//销毁链表
void SLTDestory(SLND** pphead)
{
	assert(pphead && *pphead);
	SLND* pcur = *pphead;
	while (pcur)
	{
		SLND* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	*pphead = NULL;
	printf("销毁成功!\n");
}

tset.c

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"SListNode.h"
void SListTest01()
	{
	//链表是一个一个节点组成
	//创建几个节点
	SLND* node1 = (SLND*)malloc(sizeof(SLND));
	node1->data = 1;

	SLND* node2 = (SLND*)malloc(sizeof(SLND));
	node2->data =2 ;

	SLND* node3 = (SLND*)malloc(sizeof(SLND));
	node3->data = 3;

	SLND* node4 = (SLND*)malloc(sizeof(SLND));
	node4->data = 4;

	//将四个链表连起来
	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = NULL;

	SLND* plist = node1;
	//打印链表
	SLTPrint(plist);
	}
void SListTest02(void)
{
	SLND* plist = NULL;
	SLTPushback(&plist, 1);
	SLTPushback(&plist, 3);
	SLTPushFront(&plist, 6);
	SLTPrint(plist);
	SLTPopFront(&plist);
	SLTPopback(&plist);
	SLTPrint(plist);
	SLND*ree=SLFind(plist, 1);
	SLTInsertAfter(ree, 2);
	SLTPrint(plist);
	SLTInsert(&plist, ree, 6);
	SLTPrint(plist);
	SLTErase(&plist, ree);
	SLTPrint(plist);
	SLND* pree = SLFind(plist, 6);
	SLTEraseAfter(pree);
	SLTPrint(plist);
	SLTDestory(&plist);
	SLTPrint(plist);
}

int main(void)
{
	SListTest02();
}
相关推荐
鸽子一号6 分钟前
c#之信号量Semaphore
笔记
kdxiaojie9 分钟前
Linux 驱动研究 —— I2C (5)
linux·运维·笔记·学习
会周易的程序员42 分钟前
从零构建多核CPU负载自适应控制系统
linux·c++·笔记·物联网·测试工具
茯苓gao2 小时前
机器人产业的三级火箭:卖电机、卖模组与卖整机,三种商业模式的终局推演
笔记·学习·机器人
LuminousCPP2 小时前
C 语言集中实践全记录:顺序表 + 单链表原理实现与通讯录项目实战【附可运行源码】
c语言·开发语言·数据结构·经验分享·笔记
兰令水2 小时前
hot100【acm版】【2026.7.13打卡-java版本】
java·开发语言·数据结构·算法·leetcode·面试
马里马里奥-2 小时前
大模型应用开发笔记04:LangChain 工具(Tool)与中间件(Middleware)详解
笔记·中间件·langchain
乐橙开放平台4 小时前
巡店系统笔记:乐橙 listDeviceDetailsByPage 台账 + bindDeviceLive 辅码流最小闭环
网络·笔记·物联网·自动化·音视频·智能家居
LuminousCPP5 小时前
单链表专题(应用篇):三道经典题吃透删除、反转与快慢指针
c语言·数据结构·笔记
:-)6 小时前
算法-希尔排序
数据结构·算法·排序算法