手撕单链表

目录

链表的概念和结构

单链表的实现

申请新结点

打印

尾插

头插

尾删

头删

​编辑

查找

在pos位置前插入元素

在pos位置后插入元素

删除pos位置的元素

删除pos位置之后的位置的元素​编辑

完整代码

SListNode.h

SListNode.c


链表的概念和结构

链表是一种物理存储上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的

链式结构逻辑连续,物理不一定连续

单链表的实现

无头 单向 非循环链表

申请新结点

打印

尾插

头插

尾删

头删

查找

在pos位置前插入元素

​​​​

在pos位置后插入元素

删除pos位置的元素

删除pos位置之后的位置的元素

完整代码

SListNode.h

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SLTDataType;

typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

SLTNode* BuySListNode(SLTDataType x);     //申请一个结点

void SListNodePrint(SLTNode* plist);      //打印

void SListPushBack(SLTNode** pplist, SLTDataType x);    //尾插

void SListPushfront(SLTNode** pplist, SLTDataType x);    //头插

void SListPopBack(SLTNode** pplist);    //尾删

void SListPopfront(SLTNode** pplist);    //头删

SLTNode* SListFind(SLTNode* plist, SLTDataType x);        //查找

void SListInsert(SLTNode** pplist, SLTNode* pos, SLTDataType x);    //在pos位置前插入元素

void SListInsertAfter(SLTNode* pos, SLTDataType x);   //在pos位置后插入元素

void SListErase(SLTNode** pplist, SLTNode* pos);     //删除pos位置前的元素

void SListEraseAfter(SLTNode* pos);          //删除pos位置之后的位置的元素

SListNode.c

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

#include "SListNode.h"

SLTNode* BuySListNode(SLTDataType x)            //申请一个新结点
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc failed");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

void SListNodePrint(SLTNode* plist)      //打印
{
	SLTNode* cur = plist;
	while (cur)
	{
		printf(" %d ->", cur->data);
		cur = cur->next;
	}
	printf("NULL");
	printf("\n");
}

void SListPushBack(SLTNode** pplist, SLTDataType x)    //尾插
{
	assert(pplist);
	SLTNode* newnode = BuySListNode(x);
	if (*pplist == NULL)
	{
		*pplist = newnode;
	}
	else
	{
		SLTNode* tail = *pplist;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

void SListPushfront(SLTNode** pplist, SLTDataType x)    //头插
{
	assert(pplist);
	SLTNode* newnode = BuySListNode(x);
	newnode->next = *pplist;
	*pplist = newnode;
	
}

void SListPopBack(SLTNode** pplist)    //尾删
{
	assert(pplist);

	assert(*pplist);//空链表
	//一个结点
	if ((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	//一个以上结点
	else
	{
		SLTNode* tail = *pplist;
		while (tail->next->next != NULL)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

void SListPopfront(SLTNode** pplist)    //头删
{
	assert(pplist);
	assert(*pplist);
	SLTNode* cur = *pplist;
	*pplist = (*pplist)->next;
	free(cur);
}

SLTNode* SListFind(SLTNode* plist, SLTDataType x)        //查找
{
	SLTNode* cur = plist;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void SListInsert(SLTNode** pplist, SLTNode* pos, SLTDataType x)    //在pos位置前插入元素
{
	assert(pplist);
	assert(pos);
	if (*pplist == pos)
	{
		SListPopfront(pplist, x);
	}
	else
	{
		SLTNode* cur = *pplist;
		while (cur->next != pos)
		{
			cur = cur->next;
		}
		SLTNode* newnode = BuySListNode(x);
		newnode->next = cur->next;
		cur->next = newnode;
	}
}

void SListInsertAfter(SLTNode* pos, SLTDataType x)   //在pos位置后插入元素
{
	assert(pos);
	SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

void SListErase(SLTNode** pplist, SLTNode* pos)     //删除pos位置的元素
{
	assert(pplist);
	assert(pos);
	if (*pplist == pos)
	{
		SListPopfront(pplist);
	}
	else
	{
		SLTNode* cur = *pplist;
		while (cur->next->next = pos)
		{
			cur = cur->next;
		}
		cur->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

void SListEraseAfter(SLTNode* pos)          //删除pos位置之后的位置的元素
{
	assert(pos);
	assert(pos->next);

	SLTNode* cur = pos->next;
	pos->next = cur->next;
	free(cur);
	cur = NULL;
}
相关推荐
apocelipes17 小时前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
CSharp精选营4 天前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
刘马想放假7 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠8 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦15 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园16 天前
C++20 Modules 模块详解
java·开发语言·spring
swordbob16 天前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
小小工匠16 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化