单链表(纯代码)

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语言基础之数组
c语言·数据结构·算法
taulee017 分钟前
【题解】Codeforces Round 975 (Div. 2) A~E
数据结构·c++·算法·深度优先·图论
无涯学徒199812 分钟前
L8打卡学习笔记
笔记·学习·支持向量机
快乐的流畅16 分钟前
【数据结构】图的最小生成树
数据结构·c++·图论
并不会29 分钟前
“从零开始学排序:简单易懂的算法指南“
java·数据结构·学习·算法·排序算法·重要知识
fzzf5921 小时前
Codeforces Round 976 (Div. 2) and Divide By Zero 9.0(A~E)
数据结构·c++·算法
speop1 小时前
【笔记】数据结构12
数据结构·笔记
爬树的小蚂蚁1 小时前
OceanBase 关于一号表笔记与ERROR 1060(42S21)问题
笔记·oceanbase
mez_Blog1 小时前
docker学习笔记(1.0)
笔记·学习·docker·容器
蠢蠢的打码1 小时前
8622 哈希查找
数据结构·c++·算法·链表·图论