单链表(纯代码)

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();
}
相关推荐
唐叔在学习1 分钟前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
LuH11246 分钟前
【论文阅读笔记】Learning to sample
论文阅读·笔记·图形渲染·点云
ALISHENGYA20 分钟前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
一棵开花的树,枝芽无限靠近你1 小时前
【PPTist】组件结构设计、主题切换
前端·笔记·学习·编辑器
犬余2 小时前
设计模式之桥接模式:抽象与实现之间的分离艺术
笔记·学习·设计模式·桥接模式
数据爬坡ing3 小时前
小白考研历程:跌跌撞撞,起起伏伏,五个月备战历程!!!
大数据·笔记·考研·数据分析
咖肥猫3 小时前
【ue5学习笔记2】在场景放入一个物体的蓝图输入事件无效?
笔记·学习·ue5
武昌库里写JAVA3 小时前
浅谈怎样系统的准备前端面试
数据结构·vue.js·spring boot·算法·课程设计
S-X-S3 小时前
代码随想录刷题-数组
数据结构·算法
l138494274513 小时前
每日一题(4)
java·数据结构·算法