都说C++难,那是没有学习数据结构【单链表】

2023-11-15

(❁´◡`❁)
单链表


前言

上篇顺序表结尾了解了顺序表的诸多缺点,链表的特性很好的解决了这些问题,本期我们来认识单链表。
请添加图片描述


一、链表是什么

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接依次实现的。
在这里插入图片描述

  1. 由图,链式结构在逻辑上是连续的,但是物理上不一定连续
  2. 显示中结点一般是从堆上申请出来的
  3. 从堆上申请的空间,是按照一定的策略划分的,两次申请的空间,可能连续,可能不连续,见顺序表
  4. 在这里插入图片描述

链表的分类

链表也可以分为很多种

1.  单向或者双向
2. 带头或者不带头
3. 循环或非循环

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们最常用的还是无头单向非循环链表带头双向循环链表
本篇我们实现无头单向非循环链表增删查改

二、链表的实现

基本结点结构

typedef int SLTDateType;
typedef struct SListNode
{
SLTDateType data;
struct SListNode* next;
}SListNode;
  • 头文件
//llist.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType data;
	struct SListNode* next;
}SListNode;

// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x);
// 单链表打印
void SListPrint(SListNode* plist);
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x);
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x);
// 单链表的尾删
void SListPopBack(SListNode** pplist);
// 单链表头删
void SListPopFront(SListNode** pplist);
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x);
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
void SListInsertAfter(SListNode* pos, SLTDateType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
void SListEraseAfter(SListNode* pos);
// 单链表的销毁
void SListDestory(SListNode* plist);
  • 动态申请一个节点
    在这里插入图片描述
// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x)
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	if (newnode == NULL)//申请失败
	{
		printf("malloc fail\n");
		exit(-1);
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}
	return newnode;
}                     
  • 单链表打印
    链表单个结点中,data存储数据,next存储下一个结点的地址,可以通过next访问下一个结点
    在这里插入图片描述
    在这里插入图片描述
// 单链表打印
void SListPrint(SListNode* plist)
{
	SListNode* cur = plist;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;//访问下一个结点
	}
	printf("NULL\n");
}
  • 单链表尾插
    在这里插入图片描述
    这里传入了头结点的地址的指针,是因为有可能要改变头结点的情况,传址调用幻术,如果只传入*plist,相当于只改变形参,实参不会有实际改变,通过pplist可以解决这个问题
    在这里插入图片描述
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x)
{
	SListNode* newnode = BuySListNode(x);
	if (*pplist == NULL)//空链表
	{
		*pplist = newnode;
	}
	else
	{
		SListNode* tail = *pplist;//遍历至最后插入
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}
  • 单链表的尾删
    一前一后遍历,找到空后直接free(tail),将prev->next置空即可
    在这里插入图片描述
// 单链表的尾删
void SListPopBack(SListNode** pplist)
{
	assert(pplist);
	if (*pplist == NULL)//空链表,无需删除
	{
		return;
	}
	else
	{
		SListNode* prev = NULL;
		SListNode* tail = *pplist;
		{
			while (tail->next != NULL)
			{
				prev = tail;
				tail = tail->next;
			}

			free(tail);
			tail = NULL;
			prev->next = NULL;
		}
	}
}
  • 单链表的头插
    在这里插入图片描述
    有点绕,要多想想
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x)
{
	assert(pplist);
	SListNode* newnode = BuySListNode(x);
	newnode->next = *pplist;
	*pplist = newnode;
}
  • 单链表头删
    在这里插入图片描述
    比较简单
// 单链表头删
void SListPopFront(SListNode** pplist)
{
	assert(pplist);
	if (*pplist == NULL)//链表为空
	{
		return;
	}
	else
	{
		SListNode* next = (*pplist)->next;
		free(*pplist);
		*pplist = next;
	}
}
// 单链表查找
遍历即可
SListNode* SListFind(SListNode* plist, SLTDateType x)
{
	SListNode* cur = plist;
	while (cur != NULL)
	{
		if (cur->data = x)
		{
			return cur;
		}
		cur = cur->next;
	}

	retuen NULL;
}

*单链表在pos位置之后插入x
为什么不在pos之前插入,由于我们是单向链表,需要从头遍历查找pos,如果在pos之前插入,找到pos还需找到pos之前的地址,对所传参数不友好,所以我们一般在后插入
在这里插入图片描述

//单链表在pos位置之后插入x
void SListInsertAfter(SListNode* pos, SLTDateType x)
{
	assert(pos);
	SListNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}
  • 单链表删除pos位置之后的值
    为什么不删除pos位置,同上,在逻辑上和传参不友好.
    在这里插入图片描述
// 单链表删除pos位置之后的值
void SListEraseAfter(SListNode* pos)
{
	assert(pos);
	SListNode* next = pos->next;
	if (next)
	{
		pos->next = next->next;
		free(next);
		next = NULL;
	}
}
  • 单链表的销毁
    链表不像顺序表连续删头就可以,由于链表是一个一个分散的结点,需要逐一删除
    在这里插入图片描述
// 单链表的销毁
void SListDestory(SListNode** pplist)
{
	assert(*pplist);
	SListNode* cur = *pplist;
	while (cur)
	{
		SListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pplist = NULL;
}

总结

链表相比但链表难度提升不少,对c的掌握也变大,不清晰的地方要多想多画图。还请斧正

请添加图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

都说C++难,那是没有学习数据结构【单链表】 的相关文章

  • -ffast-math 可以安全地用于典型项目吗?

    在回答我建议的问题时 ffast math 有评论指出这是危险的 我个人的感觉是 在科学计算之外 是可以的 我还假设严肃的金融应用程序使用定点而不是浮点 当然 如果你想在你的项目中使用它 最终的答案是在你的项目上测试它 看看它有多大影响 但
  • StackExchange Redis 删除所有以以下开头的键

    我有一个格式的密钥 Error 1 Error 24 Error 32 Using StackExchange Redis 我该怎么办KeyDelete在与格式匹配的所有键上Error 在另一个答案中我看到了 LUA 脚本 EVAL ret
  • 处理器关联组 C#

    我使用的是 72 核的 Windows Server 2016 我看到有两组处理器 我的 net 应用程序将使用一个或其他组 我需要能够强制我的应用程序使用我选择的组 我看到下面的代码示例 但我无法使其工作 我可能传递了错误的变量 我希望应
  • 如何在 ASP.NET MVC 中处理会话数据

    假设我想存储一个名为language id在会议中 我想我也许可以做如下的事情 public class CountryController Controller WebMethod EnableSession true AcceptVer
  • 二叉树和快速排序?

    我有一个家庭作业 内容如下 别生气 担心 我是not请你帮我做作业 编写一个程序 通过使用二分查找的快速排序方法对一组数字进行排序 树 推荐的实现是使用递归算法 这是什么意思 到目前为止 这是我的解释 正如我在下面解释的那样 我认为两者都有
  • 如何在 Google Mock 中使用可选参数来模拟方法?

    如何使用可选参数模拟方法谷歌模拟 例如 class A public void set enable bool enabled true class MockA public A MOCK METHOD1 set enable void b
  • 以编程方式更新 Wifi 网络

    我正在尝试创建一个程序 当某个 wifi 网络在范围内时 该程序会连接到该网络 即使已经连接到另一个 wifi 也是如此 我在用着简单Wifi https github com DigiExam simplewifi 基本上效果很好 除了在
  • 如何在单例类和未命名类之间进行选择?

    我会使用这样的单例 Singleton single Singleton instance single gt do it 我会使用这样的未命名类 single do it 我觉得单例模式除了具有可读的错误消息之外 与未命名的类相比没有任何
  • 如何查看每秒更新的图表中的最后 10 个数据点?

    我有这个代码 private void timer Tick object sender EventArgs e timer Stop for int i 0 i lt TOTAL SENSORS i DateTime d DateTime
  • 大小为 k 的非连续子序列的最大值的最小值

    在开始之前 我希望这个问题不是重复的 我发现了几个类似的问题 但它们似乎都没有描述完全相同的问题 但如果它是重复的 我会很高兴看到一个解决方案 即使它与我的算法不同 我一直在尝试回答这个问题 https stackoverflow com
  • 向客户端发送状态码 500 时页面未呈现

    我有一个页面 通用处理程序 我想在该页面上向客户端返回状态代码 500 以指示出现问题 我这样做 Response StatusCode 500 Response StatusDescription Internal Server Erro
  • 对列表中的一系列整数求和

    假设我有一个这样的列表 List
  • 批量插入,asp.net

    我需要获取与会员相对应的 ID 号列表 在任何给定时间处理的数量可能在 10 到 10 000 之间 我可以毫无问题地收集数据 解析数据并将其加载到 DataTable 或任何内容 C 中 但我想在数据库中执行一些操作 将所有这些数据插入表
  • 括号内声明的对象的范围

    如果我声明一个这样的对象 void main myclass objectA anotherclass true true 0 即 我通过直接调用后者的构造函数来创建一个 objectA 和另一个对象 anotherclass anothe
  • 以编程方式阻止 Vista 桌面搜索 (WORDS) 对映射网络驱动器上的 pst 文件建立索引

    经过几天的多次尝试 我没有找到任何 100 的解决方案来解决这个问题 我的搜寻和调查范围 直接访问注册表 HKLM SOFTWARE Microsoft Windows Search CrawlScopeManager Windows Sy
  • 使用 StartServiceCtrlDispatcher 与 StartService 从 C 语言启动 Windows 服务有什么区别?

    我尝试使用 StartServiceCtrlDispatcher 中所述https msdn microsoft com en us library windows desktop bb540475 v vs 85 aspx https m
  • asio::this_coro::executor 的实现是什么

    在协程函数中 我们可以添加auto ex co await asio this coro executor 获取该协程的执行者 但当我想了解它的定义时 我发现了这个 Awaitable type that returns the execu
  • C 中的等效 plpgsql 触发器

    我有一个 PostgreSQL 9 0 服务器 并且在某些表上使用继承 因此我必须通过如下触发器模拟外键 CREATE OR REPLACE FUNCTION othertable before update trigger RETURNS
  • 为什么在一行中使用这个 C++ 函数两次会导致编译错误?

    我在尝试在 Visual C 2010 中实现智能相等测试宏类型模板函数时遇到了一些麻烦 该函数与VS 中关于模板函数默认参数的错误 https stackoverflow com questions 10343177 why do i g
  • C# 使用 .Equals() 比较两个 double

    我使用 ReShaper 当我用 比较两个双精度值时 它建议我应该使用 Math 具有公差的 ABS 方法 看 https www jetbrains com help resharper 2016 2 CompareOfFloatsByE

随机推荐

  • Ubuntu 15.04 下编译Caffe2

    深度学习大神贾扬清在四月底发布了最新框架Caffe2 最近在Ubuntu15 04下编译了它的源代码 遇到一些坑 记录下来以供参考 基本安装次序如官网所述 https caffe2 ai docs getting started html
  • k8s Trouble Shooting 故障排除

    本文要讲的是k8s的故障排除 比较浅 最近刚入门 主要涵盖的内容是查看k8s对象的当前运行时信息 对于服务 容器的问题是如何诊断的 对于某些复杂的问题例如pod调度问题是如何排查的 1 查看系统的Event事件 在对象资源 pod serv
  • 一起写一个 Web 服务器

    http my oschina net leejun2005 blog 486771 一起写一个 Web 服务器 2 2015 06 06 实践项目 9 评论 Web服务器 分享到 8 本文由 伯乐在线 高世界 翻译 艾凌风 校稿 未经许可
  • java实现评论功能_Java实现评论回复功能的完整步骤

    前言 使用递归循环开发评论回复功能 适用于大部分的简单单体应用 评论功能或许是大多数的单体应用之中会用到的功能 我们会在自己所开发的项目之中进行集成该功能 大多数时候我们会将评论功能划分成以下几种 单一型 嵌套型 两层型 一 分类方式 1
  • SAP B/P 初步研究(二)

    从开发人员角度来看 B P客户创建可以试用两种方法 第一种是使用BAPI FUNCTION 第二种是使用BAPI CALL METHOD 个人更倾向于使用METHOD 因为METHOD方法只需要填充一个嵌套结构就可以实现B P所有业务视图的
  • 【STM32】制作一个bootloader

    工作环境 STM32CubeMX Keil 相关环境准备这里就不介绍了 bootloader是什么 bootloader就是单片机启动时候运行的一段小程序 这段程序负责单片机固件的更新 也就是单片机选择性的自己给自己下载程序 可以更新 可以
  • Linux C 系统编程 2-1 进程管理 进程环境

    该系列文章总纲链接 专题分纲目录 LinuxC 系统编程 本章节思维导图如下所示 思维导图会持续迭代 第一层 第二层 1 进程的启动和退出 1 1 流程 程序启动 gt 程序加载 地址分配 gt 程序退出 1 程序启动 对于二进制文件 如果
  • 浅谈State状态模式

    一 前言 状态模式在某些场合中使用是非常方便的 什么叫做状态 如果大家学过 编译原理 就会明白DFA M和NFA M 在确定有限状态机和非确定有限状态机中 状态就是最小的单元 当满足某种条件的时候 状态就会发生改变 我们可以把时间中的一个时
  • OSPF的路由器角色

    IR internal router 区域内路由器 普通区域 BR backbone router 骨干区域路由器 位于骨干区域 至少一个接口在骨干区域 ABR area border rouder 区域边界路由器 作用是连接骨干区域和普通
  • Aixcode代码自动补全插件的安装和使用

    最近在技术公众号上看到大佬们说到一款代码自动补全的智能插件aixcode 官方是这样宣传的 智能代码提示 她用强大的深度学习引擎 能给出更加精确的代码提示 代码风格检查 她有代码风格智能检查能力 帮助开发者改善代码质量 编程模式学习 她能自
  • Verilog数据类型

    作者 anekin 原作网址 http blog sina com cn s blog 615047920100ih0k html Verilog HDL有下列四种基本的值 1 0 逻辑0或 假 状态 2 1 逻辑1或 真 状态 3 x X
  • 因果推断 - 反事实

    目录 基础知识 案例实战 版权 转载前请联系作者获得授权 声明 部分内容出自因果关系之梯 已获得原作者授权 参考书籍 The Book of Why Judea Pearl 基础知识 定义 对于包含外生变量 U U U和内生变量 X X
  • mysql 显示用户_在Mysql中如何显示所有用户?

    这是一个mysql初学者经常问到的一个问题 今天我们就带大家看看是如何在Mysql中显示所有用户的 通常我们在mysql中使用SHOW DATABASES可以显示所有的数据库 SHOW TABLES将会显示所有的数据表 那么你是不是会猜测显
  • 软件版本号讲解:什么是Alpha, Beta, RC,Release

    1 软件版本阶段说明 Alpha版 此版本表示该软件在此阶段主要是以实现软件功能为主 通常只在软件开发者内部交流 一般而言 该版本软件的Bug较多 需要继续修改 Beta版 该版本相对于 版已有了很大的改进 消除了严重的错误 但还是存在着一
  • LayUI图片上传接口

    前端样式 div class layui upload drag i class layui icon xe67c i p 点击上传 或将文件拖拽到此处 p div js var uploadInst upload render elem
  • 10种React组件之间通信的方法

    组件间通信方式总结 父组件 gt 子组件 1 Props 2 Instance Methods refs 子组件 gt 父组件 3 Callback Functions 回调函数 4 Event Bubbling 事件冒泡机制 兄弟组件之间
  • 成都瀚网科技:抖店怎么上精选联盟?

    在抖音电商平台上 选定的联盟是一个非常重要的入口 对于商家来说 能够进入选定的联盟意味着更多的曝光度和流量 从而获得更好的销售机会 那么 抖店是如何进入精选联盟的呢 1 抖店如何加入特色联盟 提供优质的商品和服务 首先 抖店想要入驻所选联盟
  • 如何判断两个IP地址是否在同一个网段?什么是子网掩码?

    子网的概念挺复杂的 日常只要知道 网络传输时 只要对方IP与自己不在同一个子网 数据就会转交给网关处理 也就是路由器转发的意思 一 什么是子网掩码 在了解ip地址的网段之前 我们先来了解子网掩码 很多对网络了解不深的朋友都对子网掩码有些迷惑
  • JS的动画

    d1 hide 隐藏 d1 toggle 隐藏的显示 显示的隐藏 d1 fadeToggle 淡入淡出 d1 fadeTo fast 0 4 透明化 使用后 淡入淡出都无效包括再次透明化 d1 fadeOut fast 淡出 逐渐消失 d1
  • 都说C++难,那是没有学习数据结构【单链表】

    单链表 可有可无的目录 前言 一 链表是什么 链表的分类 二 链表的实现 总结 前言 上篇顺序表结尾了解了顺序表的诸多缺点 链表的特性很好的解决了这些问题 本期我们来认识单链表 一 链表是什么 链表是一种物理存储结构上非连续 非顺序的存储结