单链表(纯代码)

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();
}
相关推荐
冷雨夜中漫步5 小时前
Python快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
郝学胜-神的一滴6 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
Gain_chance8 小时前
34-学习笔记尚硅谷数仓搭建-DWS层最近一日汇总表建表语句汇总
数据仓库·hive·笔记·学习·datagrip
Gain_chance9 小时前
36-学习笔记尚硅谷数仓搭建-DWS层数据装载脚本
大数据·数据仓库·笔记·学习
肖永威9 小时前
macOS环境安装/卸载python实践笔记
笔记·python·macos
暗光之痕9 小时前
Unreal5研究笔记 Actor的生命周期函数
笔记·unreal engine
Gain_chance10 小时前
35-学习笔记尚硅谷数仓搭建-DWS层最近n日汇总表及历史至今汇总表建表语句
数据库·数据仓库·hive·笔记·学习
宵时待雨10 小时前
STM32笔记归纳9:定时器
笔记·stm32·单片机·嵌入式硬件
m0_7190841111 小时前
React笔记张天禹
前端·笔记·react.js
不知名XL11 小时前
day50 单调栈
数据结构·算法·leetcode