拿捏单链表

目录

引言

一:链表的定义

二:单链表的定义 

三:单链表的增删查改 

1.单链表增删查改及遍历的声明

注:在测试中创建指向头结点的指针plist 

2.二级指针应用的说明 

 3.单链表的遍历

4.创建节点 

5.单链表的插入 

(1)头插

(2) 尾插

 (3)任意位置之前插入

(4)任意位置之后插入

6.单链表的删除 

(1)头删

(2) 尾删

(3) 任意位置删除

7.单链表的查找 

8.单链表的修改 

四:关于单链表的介绍就到此为止了,青山不改,绿水长流,后会有期。 


接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧 

引言

   链表是一种常见的数据结构,它可以用来存储数据,并可以快速的进行增删查改的目的。相对于数组来说链表更加灵活和高效,数组的优势在于数组下标的随机访问,链表则可以更好的解决数组容量的大小,频繁扩容等一系列问题。

   接下来本文将介绍关于链表的定义以及单链表的增删查改,知识云游号即将发车

   辞忧提醒你请系好安全带,准备发车

一:链表的定义

1.链表是由一系列的节点构成,每个节点包含一个数据内容的数据域和一个指向下一个节点的指针的指针域。

2.每个节点是由malloc申请来的,所以每个节点是在内存空间中的堆区中,并且是在堆中随即申请的,所以各结点的地址是不连续的,是随机的。并且与在栈中申请的局部变量不同,局部变量出作用域销毁,而节点是在堆中,不销毁。

3.每个链表都包含一个头节点和一个指向头结点的指针变量,用来对链表进行各种操作。每个链表的尾节点中指针域为NULL。

二:单链表的定义 

三:单链表的增删查改 

1.单链表增删查改及遍历的声明


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SListDatatype;

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

//打印单链表数据
void SLTPrint(SLTNode*phead);

//单链表之创建节点
SLTNode* CreatNode(SListDatatype x);

//单链表之头插
void SLTPushFront(SLTNode** pphead,SListDatatype x);

//单链表之尾插
void SLTPushBack(SLTNode** pphead, SListDatatype x);

//单链表之头删
void SLTPopFront(SLTNode**pphead);

//单链表之尾删
void SLTPopBack(SLTNode **pphead);

//单链表之查找
SLTNode* SLTFindData(SLTNode** pphead, SListDatatype data);

//单链表之修改
void SLTModifyData(SLTNode** pphead, SListDatatype place,SListDatatype data);

//单链表之任意位置之前插入
void SLTPushArbit(SLTNode**pphead,SListDatatype place,SListDatatype data);

//单链表之任意位置删除
void SLTPopArbit(SLTNode** pphead, SListDatatype place);

//单链表之任意位置之后插入
void SLTPushBackArbit(SLTNode** pphead, SListDatatype place, SListDatatype data);
注:在测试中创建指向头结点的指针plist 

2.二级指针应用的说明 

二级指针顾名思义就是指向指针的指针,在最早接触指针的时候,有一个最简单的例子,就是用函数来实现两数交换,这个问题最初我们写的代码就如下

发现根本没有解决问题,主要原因是改变形参不改变实参,因此便想到运用指针的方法:

这次发现 便可以,因此要改变int类型的值必须传int*,改变int*的值必须传int**,对于单链表中的结构体也一样,改变头节点的指针,就得使用头节点指针的指针。

 3.单链表的遍历

void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d->",cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

4.创建节点 

SLTNode* CreatNode(SListDatatype x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc newnode");
		return ;
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

注:x为数据域的内容

5.单链表的插入 

(1)头插
void SLTPushFront(SLTNode** pphead,SListDatatype x)
{
	assert(pphead);
	SLTNode* newnode = CreatNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

 

(2) 尾插
void SLTPushBack(SLTNode** pphead, SListDatatype x)
{
	assert(pphead);
	SLTNode* newnode = CreatNode(x);
	//1.空链表
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else   //2.不是空链表
	{
		//找尾
		SLTNode* cur = *pphead;
		while (cur->next != NULL)
		{
			cur = cur->next;
		}
		cur->next = newnode;
	}
}

 

 (3)任意位置之前插入
//查找代码
SLTNode* SLTFindData(SLTNode** pphead, SListDatatype x)
{
	assert(pphead);
	assert(*pphead);//空链表不需查找
	SLTNode* cur = *pphead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
void SLTPushFrontArbit(SLTNode** pphead, SListDatatype place,SListDatatype data)
{
	assert(pphead);
	assert(*pphead);//空链表不能任意位置插入
	SLTNode* PushPlace = SLTFindData(pphead, place);
	if (PushPlace != NULL)
	{
		if (PushPlace == *pphead)//1.只有一个节点
		{
			SLTPushFront(pphead, data);
		}
		else//2.一个以上节点
		{
			SLTNode* newnode = CreatNode(data);
			SLTNode* cur = *pphead;
			while (cur->next != PushPlace)
			{
				cur = cur->next;
			}
			cur->next = newnode;
			newnode->next = PushPlace;
		}
	}
	else
	{
		printf("无此位置");
		return;
	}
}

 

(4)任意位置之后插入
SLTNode* SLTFindData(SLTNode** pphead, SListDatatype x)
{
	assert(pphead);
	assert(*pphead);//空链表不需查找
	SLTNode* cur = *pphead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
void SLTPushBackArbit(SLTNode** pphead, SListDatatype place, SListDatatype data)
{
	assert(pphead);
	assert(*pphead);//空链表不需查找插入
	SLTNode* PushPlace = SLTFindData(pphead, place);
	if (PushPlace)
	{
		SLTNode* newnode = CreatNode(data);
		if (*pphead == PushPlace)//头节点之后插入
		{
			(*pphead)->next = newnode;
		}
		else if(PushPlace->next==NULL)//尾节点之后插入
		{
			SLTNode* cur = *pphead;
			while (cur != PushPlace)
			{
				cur = cur->next;
			}
			cur->next = newnode;
		}
		else
		{
			SLTNode* cur = *pphead;
			while (cur != PushPlace)
			{
				cur = cur->next;
			}
			SLTNode* curr = cur->next;
			newnode->next = curr;
			cur->next = newnode;
		}
	}
	else
	{
		printf("找不到");
		return;
	}
}

 

6.单链表的删除 

(1)头删
void SLTPopFront(SLTNode** pphead)
{
	assert(pphead);
	assert(*pphead);//空链表不能删除
	//1.只有一个节点
	if ((*pphead)->next == NULL)
	{
		*pphead = NULL;
		free(*pphead);
	}
	else  //2.一个以上节点
	{
		SLTNode* del = *pphead;
		*pphead = del->next;
		del->next = NULL;
		free(del);
	}
}

 

(2) 尾删
void SLTPopBack(SLTNode** pphead)
{
	assert(pphead);
	assert(*pphead);//空链表不能删除
	//1.只有一个节点
	if ((*pphead)->next == NULL)
	{
		*pphead = NULL;
		free(*pphead);
	}
	else
	{
		SLTNode* cur = *pphead;
		while (cur->next->next != NULL)
		{
			cur = cur->next;
		}
		cur->next = NULL;
		free(cur->next);
	}
}

 

 

(3) 任意位置删除
//查找
SLTNode* SLTFindData(SLTNode** pphead, SListDatatype x)
{
	assert(pphead);
	assert(*pphead);
	SLTNode* cur = *pphead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
void SLTPopArbit(SLTNode** pphead, SListDatatype place)
{
	assert(pphead);
	assert(*pphead);//空链表不能查找删除
	SLTNode* PopPlace = SLTFindData(pphead, place);
	if (PopPlace != NULL)
	{
		if (*pphead == PopPlace)//只有一个节点
		{
			SLTPopFront(pphead);
		}
		else
		{
			SLTNode* cur = *pphead;
			while (cur->next != PopPlace)
			{
				cur = cur->next;
			}
			SLTNode* del = PopPlace;
			cur->next = del->next;
			free(del);
		}
	}
	else
	{
		printf("无此位置");
		return;
	}
}

 

7.单链表的查找 

 

SLTNode* SLTFindData(SLTNode** pphead, SListDatatype x)
{
	assert(pphead);
	assert(*pphead);
	SLTNode* cur = *pphead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

8.单链表的修改 

//指定位置修改
void SLTModifyData(SLTNode** pphead, SListDatatype place,SListDatatype data)
{
	assert(pphead);
	assert(*pphead);//空链表不能修改
	SLTNode* ret = SLTFindData(pphead, place);
	ret->data = data;
}

四:关于单链表的介绍就到此为止了,青山不改,绿水长流,后会有期。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/389466.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux操作系统——命名管道

我们前面说的管道都是只能具有血缘关系的进程进行进程间通信&#xff0c;如果我想让两个毫不相干的进程进行通信呢&#xff1f;那就需要来谈谈命名管道了。 命名管道 管道应用的一个限制就是只能在具有共同祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。如果我们想…

软考 系统分析师系列知识点之信息系统战略规划方法(11)

接前一篇文章&#xff1a;软考 系统分析师系列知识点之信息系统战略规划方法&#xff08;10&#xff09; 所属章节&#xff1a; 第7章. 企业信息化战略与实施 第4节. 信息系统战略规划方法 7.4.7 价值链分析法 价值链分析&#xff08;Value Chain Analysis&#xff0c;VCA&am…

【C++】---类和对象(中)默认成员函数 和 操作符重载

前言&#xff1a; 假如一个类中既没有成员变量也没有成员函数&#xff0c;那么这个类就是空类&#xff0c;空类并不是什么都没有&#xff0c;因为所有类都会生成如下6个默认成员函数&#xff1a; 一、构造函数 1、构造函数的定义及其特性 对于日期类对象&#xff0c;我们可…

pytest教程-10-allue2生成html报告

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest-html生成html报告的方法&#xff0c;本小节我们讲解一下使用allue2生成html报告。 自动化测试执行完成后我们需要展示给其他人看&#xff0c;这就要有自动化测试报告了。复杂的测试报告…

稳态准直太阳光模拟器

概述 稳态准直太阳光模拟器是一种用于模拟太阳光的设备。它能够产生高强度、高稳定性的太阳光&#xff0c;用于太阳能电池、太阳能热利用等领域的研究和实验。 稳态准直太阳光模拟器通常由以下几个部分组成&#xff1a; 光源&#xff1a;采用强度和颜色温度与太阳光接近的光源…

Rust 语言学习杂谈 (end) (各种工作中遇到的疑难杂症)

1.在运行 “cargo build --release” 的时候&#xff0c;到底发生了什么&#xff1f; 源 (GPT4.0) : 当我们运行 cargo build --release 命令时&#xff0c;实际上在进行一系列复杂的步骤来编译和构建 Rust 项目的发布版本。这个过程大致可以分解为以下几个步骤&#xff1a;…

2024年【危险化学品经营单位安全管理人员】考试报名及危险化学品经营单位安全管理人员考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位安全管理人员考试报名是安全生产模拟考试一点通总题库中生成的一套危险化学品经营单位安全管理人员考试资料&#xff0c;安全生产模拟考试一点通上危险化学品经营单位安全管理人员作业手机同步练习…

基于GPT一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

单片机学习笔记---直流电机驱动(PWM)

直流电机介绍 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极&#xff0c;当电极正接时&#xff0c;电机正转&#xff0c;当电极反接时&#xff0c;电机反转 直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&#xff08;转子&#xff09;和换向器…

正向代理和反向代理

文章目录 概述正向代理反向代理主要用途 概述 正向代理和反向代理都是网络中常见的代理类型&#xff0c;用于在客户端和服务器之间进行通信。 正向代理&#xff08;Forward Proxy&#xff09;是位于客户端和目标服务器之间的代理服务器。当客户端发送请求时&#xff0c;请求会…

批量梯度下降、随机梯度下降、小批量梯度下降

一、批量梯度下降&#xff08;Batch Gradient Descent,BGD&#xff09; 在批量梯度下降中&#xff0c;每次迭代都使用整个训练集的数据进行梯度计算和参数更新。也就是说&#xff0c;每次迭代都对所有的样本求取梯度&#xff0c;然后更新参数。由于要处理整个训练集&#xff0c…

算法沉淀——优先级队列(堆)(leetcode真题剖析)

算法沉淀——优先级队列 01.最后一块石头的重量02.数据流中的第 K 大元素03.前K个高频单词04.数据流的中位数 优先队列&#xff08;Priority Queue&#xff09;是一种抽象数据类型&#xff0c;它类似于队列&#xff08;Queue&#xff09;&#xff0c;但是每个元素都有一个关联的…

WEB APIs(2)

应用定时器可以写一个定时轮播图&#xff0c;如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport&qu…

如何在电脑和 SD 卡上恢复已删除 MOV等视频文件

MOV 是 Apple 创建的多媒体容器。您可能已经意识到&#xff0c;用 macOS QuickTime Player 录制的视频是以 MOV 格式保存的&#xff0c;而且 MOV 在 Windows 上也兼容。我们可能已经保存了很多 MOV 格式的视频。但是&#xff0c;如果这些 MOV 文件丢失或被意外删除怎么办&#…

Python二级考试笔记

Python二级考试笔记【源源老师】 01. 字符串 1. 常规功能合集 字符串本身有一些功能&#xff0c;有些之前运用过&#xff0c;这里总结如下&#xff1a; # 功能一&#xff1a;判断字符串类型 print(type("Hello")) print(str(123)) # 转换# 功能二&#xff1a;连…

OpenCV Mat实例详解 一

OpenCV中的Mat是一个类&#xff0c;它用存储图像信息。由两部分数据组成&#xff1a;矩阵头和像素值矩阵。矩阵头包含矩阵尺寸、存储方法、存储地址等信息&#xff0c;而像素值矩阵则存储实际的像素值数据。 Mat类在OpenCV中有十分重要的作用&#xff0c;图像信息的载入、保存、…

【知识图谱--第三讲知识图谱的存储与查询】

知识图谱的存储与查询 基于关系型数据库的知识图谱存储基于原生图数据库的知识图谱存储原生图数据库实现原理浅析 基于关系型数据库的知识图谱存储 基于原生图数据库的知识图谱存储 原生图数据库实现原理浅析

每日一题——LeetCode1437.是否所有1都至少相隔k个元素

方法一 两次遍历&#xff1a; 第一次遍历保存所有1的位置到res里&#xff0c;第二次遍历res检查是否所有相邻元素之间间隔都>k var kLengthApart function(nums, k) {let res[]for(let i0;i<nums.length;i){if(nums[i]1){res.push(i)}}for(let i1;i<res.length;i){…

Python 中实现线性搜索算法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 前言 线性搜索算法&#xff0c;也称为顺序搜索算法&#xff0c;是一种简单但常用的搜索技术&#xff0c;用于查…

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程 第一篇 下载Windows2.03第二篇 配置Windows2.03虚拟机机器环境第三篇 启动Windows2.03系统 第一篇 下载Windows2.03 1.Windows2.0原版软盘下载地址是 暂不提供&#xff0c;后续更新 2.Windows2.03虚拟机镜像下…