当前位置: 首页 > news >正文

【数据结构】链表

目录

数据结构之链表::

                                SList.h

                                1.链表的概念及结构

                                2.链表的分类 

                                SList.c

                                3.动态申请一个结点                              

                                4.单链表打印

                                5.单链表销毁

                                6.单链表头插

                                7.单链表头删

                                8.单链表尾插

                                9.单链表尾删

                              10.单链表查找

                              11.单链表在pos之前插入

                              12.单链表在pos之后插入

                              13.删除pos位置

                              14.删除pos后面位置                              


数据结构之链表::

SList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDataType;
typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;
SListNode* next为C++中的语法 将其封装成了类
void SListPrint(SLTNode* phead);
void Destory(SLTNode** pphead);
void SListPushFront(SLTNode** pphead, SLTDataType x);
void SListPushBack(SLTNode** pphead, SLTDataType x);
void SListPopBack(SLTNode** pphead);
void SListPopFront(SLTNode** pphead);
SLTNode* SListFind(SLTNode* phead, SLTDataType x);
在pos之前插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
在pos之后插入
void SListInsertAfter(SLTNode* pos, SLTDataType x);
删除pos位置
void SListErase(SLTNode** pphead, SLTNode* pos);
删除pos后面位置
void SListEraseAfter(SLTNode* pos);

1.链表的概念及结构

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

注意:

1.从上图可以看出,链式结构在逻辑上是连续的,但是在物理上不一定连续.

2.现实中的结点一般都是从堆上申请出来的.

3.从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续.

2.链表的分类

实际中链表的结构非常多样,以下情况组合起来就有8种链表结构.

1.单向或者双向 

 

2.带头或者不带头

 3.循环或者非循环 

 虽然有这么多的链表结构,但是我们实际中最常用还是两种结构. 

无头单向非循环链表:
结构简单,一般不会用来单独存数据,实际上更多是作为其他数据结构的子结构,如哈希桶,图的邻接表等.
带头双向循环链表:
结构最复杂,一般用来单独存储数据,实际中使用到的链表数据结构,都是带头双向循环链表,这个结构虽然复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了.

SList.c

3.动态申请一个结点

SLTNode* BuySLTNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;return newnode;
}

4.单链表打印

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

5.单链表销毁

void Destory(SLTNode** pphead)
{assert(pphead);SLTNode* cur = *pphead;while (cur != NULL){SLTNode* next = cur->next;free(cur);cur = next;}*pphead = NULL;
}

6.单链表头插

void SListPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySLTNode(x);newnode->next = *pphead;*pphead = newnode;
}

7.单链表头删

void SListPopFront(SLTNode** pphead)
{assert(pphead);温柔的检查if (*pphead == NULL){return;}暴力的检查//assert(*pphead != NULL);SLTNode* del = *pphead;*pphead = (*pphead)->next;free(del);del = NULL;
}

8.单链表尾插

void SListPushBack(SLTNode** pphead, SLTDataType x)
{1.链表是空2.链表非空链表为空 插入第一个结点 要改变的是SListNode* 用的是结构体指针的指针链表不为空 尾插要改变的是结构体SListNode的成员 用的是结构体指针assert(pphead);SLTNode* newnode = BuySLTNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}

9.单链表尾删

void SListPopBack(SLTNode** pphead)
{assert(pphead);温柔的检查——为空不删if (*pphead == NULL){return;}暴力的检查//assert(*pphead != NULL);1.一个结点 2.多个结点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{找尾SLTNode* prev = NULL;/*SLTNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}prev->next == NULL;free(tail);tail = NULL;*/SLTNode* tail = *pphead;while (tail->next->next != NULL){tail = tail->next;}prev->next = NULL;free(tail->next);tail->next = NULL;}
}

10.单链表查找

链表中的查找函数可以替代其修改函数
SLTNode* SListFind(SLTNode* phead, SLTDataType x)
{SLTNode* cur = phead;while (cur){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}

11.单链表在pos之前插入

void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead);assert(pos);if (pos == *pphead){SListPushFront(pphead, x);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;pos不在链表中 pos不在链表中 prev为空还没有找到pos 说明pos传错了assert(prev);}SLTNode* newnode = BuySLTNode(x);prev->next = newnode;newnode->next = pos;}
}

12.单链表在pos之后插入

void SListInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = BuySLTNode(x);newnode->next = pos->next;pos->next = newnode;
}

13.删除pos位置

void SListErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);assert(pos);if (*pphead == pos){SListPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;检查pos不是链表中结点 参数传错的情况assert(prev);}prev->next = pos->next;free(pos);//pos = NULL;此代码并不会改变pos 使用人在main函数将其置空}
}

14.删除pos后面位置

void SListEraseAfter(SLTNode* pos)
{assert(pos);if (pos->next == NULL){return;}else{SLTNode* next = pos->next;pos->next = next->next;free(next);}
}
单链表:只适合头插头删——O(1)
任意位置高效插入删除——双向链表
进阶:删除pos位置 要求是O(1) 替换法删除
缺陷:pos不能是尾结点 解决方法:将链表改成循环链表
进阶:在pos位置之前插入 要求是O(1)
方法:在pos位置后创造结点+替换法
newnode = BuySListNode(pos->val); 
pos->val = x;


                              

相关文章:

【数据结构】链表

目录 数据结构之链表&#xff1a;&#xff1a; SList.h 1.链表的概念及结构 2.链表的分类 SList.c 3.动态申请一个结点 4.单链表打印 5.单链表销毁 6.单链表头插 7.单链表头删 8.单链表尾插 9.单链表尾删 10.单链表查找 11.单链表在pos之前插入…...

一文讲明Hystrix熔断器

前言 解决问题: 主要防止服务器集群发生雪崩, 起到对服务器的保护作用 GitHub地址&#xff1a;https://github.com/Netflix/Hystrix/wiki 1 Hystrix是什么 1.1 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系&#xff0c;每个依赖关系在某些时候将不…...

第12篇:Java类核心构成要素分析

目录 1、Java类构成要素 1.1 如何定义类 1.2 如何定义变量 1.2.1 类变量 1.2.2 实例变量...

记一次 .NET 某医保平台 CPU 爆高分析

一&#xff1a;背景 1. 讲故事 一直在追这个系列的朋友应该能感受到&#xff0c;我给这个行业中无数的陌生人分析过各种dump&#xff0c;终于在上周有位老同学找到我&#xff0c;还是个大妹子&#xff0c;必须有求必应 &#x1f601;&#x1f601;&#x1f601;。 妹子公司的…...

滤波算法 | 无迹卡尔曼滤波(UKF)算法及其MATLAB实现

目录简介UKF滤波滤波流程和公式MATLAB程序结论简介 本文接着分享位姿跟踪和滤波算法中用到的一些常用程序&#xff0c;希望为后来者减少一些基础性内容的工作时间。以往分享总结见文章&#xff1a;位姿跟踪 | 相关内容目录和链接总结&#xff08;不断更新中~~~&#xff09; 本…...

JAVA开发(运行JAR包怎么指定虚拟机内存大小)

我们都使用过 java -jar xxx.jar包去运行jar包。但是有时候要指定jar包运行时内存&#xff0c;该怎么做&#xff0c;而且设置多大怎么衡量&#xff0c;很多人从来没有了解过。 背景&#xff1a; 我们开发java程序&#xff0c;可能涉及到开发环境&#xff0c;测试环境&#x…...

领导力的终极奥义

过去&#xff0c;我曾多次演讲、著书&#xff0c;把自己在长达半个世纪的经营实践中所体悟到的经营思想和方法告诉中国的企业家。 但是&#xff0c;对于任何一家企业来说&#xff0c;不管它倡导了多么高尚的经营哲学&#xff0c;不管它构建了多么精致的管理系统&#xff0c;这样…...

1-MATLAB APP Design-图像的输入与输出

一、APP 界面设计展示 新建一个空白的APP,在此次的学习中,我们会用到编辑字段(文本框)、 按钮、坐标区和面板,首先在界面中拖入一个编辑字段(文本框),在文本框中输入内容:图形的输入与输出,调整背景颜色,字体的颜色为黑色,字体的大小调为25....

【C++】内存管理

目录一、C/C内存分布二、C内存管理方式2.1、new/delete操作内置类型2.2、new和delete操作自定义类型三、operator new与operator delete函数3.1、operator new与operator delete函数四、new和delete的实现原理4.1、内置类型4.2、自定义类型五、定位new表达式(placement-new)六、…...

Dilworth定理

偏序关系 设RRR是集合AAA的一个二元关系&#xff0c;若RRR满足&#xff1a; 1.自反性:∀x∈A\forall x \in A∀x∈A&#xff0c;有xRxxRxxRx 2.反对称性&#xff1a;∀x,y∈A\forall x,y \in A∀x,y∈A&#xff0c;若xRy,yRxxRy,yRxxRy,yRx&#xff0c;则xyxyxy 3.传递性&…...

使用loading动画让你的条件渲染页面更高级

前言在我们做项目的使用常常会使用条件渲染去有选择的给用户展示相关页面&#xff0c;如果渲染的数据或场景比较多比较复杂&#xff0c;那么往往需要3、4s的时间去完成&#xff0c;用户点击了之后就会陷入3、4s的空白期&#xff0c;并且这段时间屏幕是处于一种”未响应“的状态…...

Renegade:基于MPC+Bulletproofs构建的anonymous DEX

1. 引言 白皮书见&#xff1a; Renegade Whitepaper: Protocol Specification, v0.6 开源代码见&#xff1a; https://github.com/renegade-fi/renegade&#xff08;Renegade p2p网络每个节点的核心网络和密码逻辑&#xff09;https://github.com/renegade-fi/mpc-bulletpr…...

二、Plugin The chain/event/query function

The chain function 链函数是所有数据处理都在其中进行的函数。在简单过滤器的情况下&#xff08;本节示例的情况&#xff09;&#xff0c;_chain()函数大多是线性函数——因此对于每个传入的缓冲区&#xff0c;也将输出一个缓冲区。下面是一个非常简单的chain函数的实现: sta…...

了解 PostgreSQL 的扩展查询协议

1.介绍 本篇博客用于解释扩展协议的工作原理以及它与简单查询的区别。 2.简单查询 在PostgreSQL中&#xff0c;客户端连接能够发起两种类型的查询&#xff1a;简单查询和扩展协议查询。 简单查询顾名思义。 当启动 psql 客户端连接到pg服务器时&#xff0c;几乎所有发送的…...

接入网关和隔离网关

文章目录1. 什么是网关&#xff1f;2. 网关的作用是什么&#xff1f;3. 接入网关和隔离网关1. 什么是网关&#xff1f; 网关&#xff08;Gateway&#xff09;是一种网络设备&#xff0c;通常用于将不同网络之间的流量进行转发和路由&#xff0c;将一个网络连接到另一个网络&…...

实用指南:如何在Anolis OS上轻松使用 Kata 安全容器?

文/云原生SIG本篇文章我们将详细介绍怎么轻松在 Anolis OS 上使用 Kata Containers 安全容器&#xff0c;我们将介绍 Kata Container 社区于 2022 年 10 月 10 日最新发行的 Kata3.0.0 的安装部署方式&#xff0c;3.0.0 版本包含了基于袋鼠 RunD 开源的最新 Rust Kata runtime …...

如何锁定Word文档部分文字不被修改

我们知道&#xff0c;想要保护Word文档的内容无法随意更改&#xff0c;可以设置“限制编辑”的保护模式。 那如果实际工作中&#xff0c;只需要固定的一部分内容不能编辑&#xff0c;可以实现吗&#xff1f;答案是肯定的&#xff0c;今天就来说说如何设置Word文档部分文字可修…...

聊聊8万8的私董会,很扎心

聊聊8万8的私董会&#xff0c;很扎心 道几句真心话&#xff0c;很扎心&#xff0c;但也很现实。 如果你喜欢刷抖音&#xff0c;这种感觉应该会更加明显。 股市哀鸿遍野&#xff0c;实体一地鸡毛&#xff0c;我们办公室楼下的门面换了一波又一波。 别说那些不起眼的小生意&a…...

卷积网络与全连接网络的区别

问题卷积神经网络是一类包含卷积计算且具有深度结构的前馈神经网络&#xff0c;是深度学习。卷积神经网络具有表征学习能力&#xff0c;能够按其阶层结构对输入信息进行平移不变分类&#xff0c;因此也被称为“平移不变人工神经网络。全连接神经网络是具有多层感知器的的网络&a…...

【5000左右电脑配置清单】预算不高于5000,不带显示器的电脑配置清单推荐

由于本人是学生党经济有限&#xff0c;预算不高于5000元配一套电脑主机&#xff0c;说实话5000左右的电脑配置已经很好了&#xff0c;今天站长整理了几款配置给大家参考参考&#xff0c;更多电脑配置还请继续关注西安SEO优化站点&#xff01; 配置1&#xff1a; <CPU> I5…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...