单链表(纯代码)

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();
}
相关推荐
龙仔7252 小时前
RustDesk 完整笔记
运维·笔记·rust·远程工具·rustdesk
Livia要学习3 小时前
Python2和Python3字典底层原理
数据结构
HJX_07243 小时前
嵌入式软件C语言八股文复习笔记5——编译、链接与底层硬核机制
c语言·开发语言·笔记
青梅橘子皮3 小时前
STL---map/set... “家族“详解(从使用到底层)(1)
数据结构·算法
摇滚侠3 小时前
《SpringBoot 3:入门与应用实战》第 15 章 生产级特性 监控指标 Metrics 阅读笔记
java·spring boot·笔记
噜~噜~噜~4 小时前
操作系统笔记-1.1.3 操作系统的特征
笔记·操作系统
杨先生哦4 小时前
【2026热端攻防系列 10/12】前端凭据安全深度攻防:Cookie/Storage劫持、会话固定、凭据泄露与浏览器最新加固方案
前端·笔记·安全·web安全
天天爱吃肉82184 小时前
# 商用车多体动力学实战笔记|第7篇:制动系统与制动热衰退、ABS滞环控制
大数据·人工智能·笔记·python·嵌入式硬件·汽车
xiaoyuchidayuma5 小时前
【交流绕组及其磁动势-典型交流绕组结构(绘制绕组展开图)】
笔记·学习
崔高杰5 小时前
【自动阅读笔记】Inference-Time Scaling for Generalist Reward Modeling
人工智能·笔记·机器学习