链表入门(单链表讲)

链表

  • 1.链表
    • 1.1 链表概念及其结构
    • 1.2 链表的分类
  • 2.单链表代码实现
    • 2.1 单链表的定义
    • 2.2 单链表的初始化
    • 2.3 单链表的新增结点
    • 2.4 单链表的打印
    • 2.4 单链表的插入
      • 2.4.1 头插
      • 2.4.2 尾插
      • 2.4.3 任意位置插入
    • 2.5 单链表的删除
      • 2.5.1 头删
      • 2.5.2 尾删
      • 2.5.3 任意位置删除
    • 2.6 单链表的查找及其修改

1.链表

1.1 链表概念及其结构

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

  • 链表结构如图所示:
    请添加图片描述

1.2 链表的分类

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

  1. 单向或者双向
    >

  2. 带头或者不带头

  3. 循环或者非循环

虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构: 在这里插入图片描述

  1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
  2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

2.单链表代码实现

2.1 单链表的定义

我们在了解线性结构最重要的就是明白这个结构是如何定义的,是怎样的一种结构。这里单链表的定义,我们考虑的是我们需要这个结构中包含什么,这里我们需要的是一个数据域和一个指针域数据域用于存储数据,指针域用于链接每个单链表节点。行,我们来rua一下:

typedef int SLTDateType;//typedef 一下,方便我们更改所需存储的类型
typedef struct SListNode
{SLTDateType data;//数据域,用于存储数据struct SListNode* next;//指针域,用于链接下一个结点
}SLTNode;

2.2 单链表的初始化

单链表一般不直接提供初始化接口,是因为单链表的初始化不需要额外的方法来完成,可以通过其他操作来实现。

一般而言,单链表的初始化可以分为两种方式:

  1. 首先创建一个空链表,然后逐个插入节点,直到构建完整的链表。
SLTNode* plist = NULL;//后续只需要不断插入新的结点就可以
  1. 直接在创建链表的过程中完成节点的插入操作,不需要单独的初始化方法。

因此,为了简化接口设计和操作复杂度,单链表通常不提供单独的初始化接口,而是通过其他操作来实现链表的构建和初始化。

2.3 单链表的新增结点

这里就可以看到我们在为一个指针开辟空间后就立马初始化了,和上述第二种初始化的方法相同。

SLTNode* SLTNewNode(SLTDateType x)
{SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode));//开辟一个链表结点大小的空间if (node == NULL)//检测是否开辟成功{perror("malloc fail");return NULL;}node->data = x;node->next = NULL;return node;
}

2.4 单链表的打印

为了方便测试一般我们会使用链表打印接口来查看检测。

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

2.4 单链表的插入

这里涉及到单链表的一个难点,就是这里需要二级指针,我们需要更改一级指针内的元素数据,所以需要用二级指针来更改。就例如我们要改变一个数据类型的值,需要一级指针一样。

在这里插入图片描述

2.4.1 头插

在链表第一个结点前插入。

void SLTPushFront(SLTNode** ppa, SLTDateType x)
{assert(ppa);//&plist(ppa)不可能为空,所以需要检测SLTNode* newnode = SLTNewNode(x);newnode->next = *ppa;//新节点的next指针指向链表开头(*ppa)*ppa = newnode;//更新头指针
}

2.4.2 尾插

在链表最后结点后插入

void SLTPushBack(SLTNode** ppa, SLTDateType x)
{assert(ppa);	SLTNode* newnode = SLTNewNode(x);if (*ppa == NULL) //判断链表是否为空{*ppa = newnode;}else{//找尾操作,这里单链表我们只能使用遍历来实现,当找到一个节点的next指针指向null时,就代表找到尾了。SLTNode* tail = *ppa;while (tail->next){tail = tail->next;}tail->next = newnode;}
}

2.4.3 任意位置插入

pos前位置插入,我们知道了尾插,这里就相当于把pos位置当做尾,去找pos位置,然后再用头插的思路完成。

//任意位置插入(pos前插入)
void SLTInsertF(SLTNode** ppa, SLTNode* pos, SLTDateType x)
{assert(ppa);assert(pos);if (pos == *ppa){SLTPushFront(ppa, x);}else {SLTNode* tmp = SLTNewNode(x);SLTNode* prev = *ppa;while (prev->next != pos){prev = prev->next;}prev->next = tmp;tmp->next = pos;}
}

pos位置后插入:学习了任意位置插入,我们其实可以把头插和尾插的实现过程改成调用任意位置插入接口

void SLTInsertB(SLTNode** ppa, SLTNode* pos, SLTDateType x)
{assert(ppa);if (pos == NULL){SLTPushBack(ppa, x);}else{SLTNode* newnode = SLTNewNode(x);SLTNode* cur = *ppa;while (cur != pos->next){cur = cur->next;}pos->next = newnode;newnode->next = cur;}
}

2.5 单链表的删除

2.5.1 头删

头删的思路就是把头指针指向下一个结点,然后释放开始的结点。

void SLTPopFront(SLTNode** ppa)
{assert(ppa);assert(*ppa);SLTNode* tmp = *ppa;*ppa = tmp->next;free(tmp);tmp = NULL;
}

2.5.2 尾删

尾删道理是相通的,找到尾指针,但也要保留尾指针的前一个指针,因为需要在删除尾指针后,把前一个尾指针的next指向空。

void SLTPopBack(SLTNode** ppa)
{assert(ppa);assert(*ppa);if ((*ppa)->next == NULL){free(*ppa);*ppa = NULL;}else{SLTNode* prev = *ppa;SLTNode* tail = prev->next;while (tail->next){prev = prev->next;tail = tail->next;}prev->next = tail->next;free(tail);tail = NULL;} 
}

2.5.3 任意位置删除

意思相近与尾删。

void SLTEraser(SLTNode** ppa, SLTNode* pos)
{assert(ppa);assert(*ppa);if ((*ppa)->next == NULL||pos==*ppa) {SLTPopFront(ppa);}else{SLTNode* prev = *ppa;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}

2.6 单链表的查找及其修改

链表查找就是对应data,然后遍历返回比较简单,修改的话就是根据返回访问data进行赋值修改

SLTNode* SLTFind(SLTNode* pa, SLTDateType x)
{SLTNode* cur = pa;while (cur){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PickerView案例10-国旗选择界面02 Objective-C预言】

一、好了,我们继续来实现这个国旗选择界面: 1.它的界面里面,是不是很简单,就一个UIPickerView,就完事儿了 然后,显示的每一行内容呢, 1)一个文字Label 2)一个图片 那大家应该有意识,它返回的应该是一个View,对吧, 代理方法里面,有一个返回View的,viewForRow…

Django:五、登录界面实现动态图片验证码

一、下载包 pip install pillow 二、代码 这是一个函数,无输入,返回两个值。一个值是图片,一个值是图片中的数字及字母。 需要注意:font_fileMonaco.ttf 是一个验证码字体文件,如有需要,可三连私信。 …

【逆向】在程序空白区添加Shellcode

目录 硬编码 内存对齐和文件对齐 节表 实战 滴水逆向03-17 #include <windows.h>LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) …

Pycharm 搭建 Django 项目,看完这一篇就够了

1. 安装需求 在使用 python 框架 Django 需要注意下面事项 Pycharm 版本是专业版而不是社区版本Pycharm 配置好了 python 解释器 &#xff08;一般我们现在用的都是python3&#xff09;我自己使用的是 Pycharm 版本是2020.1.2 2. 准备工作 2.1 新建项目 首先我们打开 Pycharm …

Linux离线安装elasticsearch|header|kibna插件最详细

1.准备软件安装包 [hadoophost152 elasticsearch]$ ll -rw-r--r--. 1 hadoop hadoop 515807354 9月 23 23:40 elasticsearch-8.1.1-linux-x86_64.tar.gz -rw-r--r--. 1 hadoop hadoop 1295593 9月 23 23:48 elasticsearch-head-master.tar.gz -rw-r--r--. 1 hadoop hadoop…

记录一个 GUI 库的对比测试结果

1&#xff0c;Java 的 JavaFX 2&#xff0c;golang 的 Fyne 1, Java 测试的是一个俄罗斯方块的 GUI 程序。一切正常。 2&#xff0c;Golang github 的原仓库网络问题&#xff0c;没能测试上&#xff0c;使用以下库 https://gitee.com/mirrors/Fyne 下载代码后提示“编译失…

Tomcat 与 JDK 对应版本关系

对应关系 Tomcat版本 jdk版本11.0.x JDK 21及以后10.1.x JDK11及以后10.0.xJDK1.8及以后9.0.x JDK1.8及以后8.5.xJDK1.7及以后8.0.x JDK1.7及以后 查看对应关系方法&#xff1a; 登陆Tomcat官网&#xff1a;Apache Tomcat - Welcome! 结果&#xff1a;

Picgo

title: “Picgo” createTime: 2021-07-01T12:05:5808:00 updateTime: 2021-07-01T12:05:5808:00 draft: false author: “name” tags: [“未标签”] categories: [“未分类”] description: “测试的” picgo 地址 : /home/zhu/software/node/node-v14.15.0-linux-x64/bin文…

河北吉力宝以步力宝健康鞋引发的全新生活生态商

在当今瞬息万变的商业世界中&#xff0c;成功企业通常都是那些不拘泥于传统、勇于创新的先锋之选。河北吉力宝正是这样一家企业&#xff0c;通过打造一双步力宝健康鞋&#xff0c;他们以功能性智能科技穿戴品为核心&#xff0c;成功创造了一种结合智能康养与时尚潮流的独特产品…

C#读取CAD文件(dwg/dxf)并处理

文章目录 一、前言二、调研过程2.1 CAD相关2.2 DWG2.3 DXF2.4 小结三、解析CAD的库3.1 netDxf3.2 Teigha3.2.1 官网获取3.2.2 网上获取四、图形计算一、前言 需求: 项目要求识别CAD图纸(图纸内容与现实事物比例是1:1)中的内容,并提取出一些关键信息。 这里的CAD图纸是指C…

unity 实用框架

单例模式基类 类不继承mono的单例基类 /// <summary> /// 单例基类 /// </summary> //泛型解决&#xff0c;给他一个约束要么是这个类本身要么是它的子类 public class SingleBase<T>where T : SingleBase<T> {protected SingleBase() { }//线程锁。…

C++ 类和对象(4)构造函数

C的目标之一是让使用类对象就像使用标准类型一样&#xff0c;但是常规的初始化语法不适用于类似类型Stock&#xff1a; int year 2001&#xff1b; struct thing {char * pn;int m; }; thing amabob {"wodget",-23}; //有效初始化 Stock hot {"Sukies Autos…

Leetcode 992. K 个不同整数的子数组

文章目录 题目代码&#xff08;9.27 首刷看解析&#xff09; 题目 Leetcode 992. K 个不同整数的子数组 代码&#xff08;9.27 首刷看解析&#xff09; 滑动窗口&#xff0c;恰好转换为&#xff1a;最多K个不同的数 - 最多K-1个不同的数 class Solution { public:int subarr…

kafka伪集群部署,使用KRAFT模式

1:拉去管理kafka界面UI镜像 docker pull provectuslabs/kafka-ui2:拉去管理kafka镜像 docker pull bitnami/kafka3:docker-compose.yml version: 3.8 services:kafka-1:container_name: kafka1image: bitnami/kafka ports:- "19092:19092"- "19093:19093&quo…

测试用例的八大基本准则

测试用例的八大基本准则 测试用例的八大基本准则功能测试性能测试兼容性测试安全测试可靠性测试易用性测试数据库测试接口测试 测试案例 测试用例的八大基本准则 上节测试用例的设计中我们讨论如何设计一个测试用例&#xff0c;知道了测试用例的设计有&#xff1a;“边界值&am…

Linux命令(87)之pwd

linux命令之pwd 1.pwd介绍 linux命令pwd(全称&#xff1a;print working directory)用来列出当前目录 2.pwd用法 pwd [参数] pwd参数(了解即可&#xff0c;99.99%用不到) 参数说明-L显示逻辑路径-P显示实际物理路径 3.实例 3.1.显示当前目录 命令&#xff1a; pwd [ro…

如何制作gif动图gif (多图合成gif、GIF录制软件、视频制作成GIF动图)

文章目录 1 在线制作多图合成gif动画2 GIF录制软件3 将现有的视频 制作成GIF动图 1 在线制作多图合成gif动画 在线制作gif动画链接:https://www.matools.com/gif ①选择需要制作gif动画的图片将其添加 ②调整时间间隔&#xff0c;图片宽高等设置 ③一键生成gif ④下载到本…

目标检测YOLO实战应用案例100讲-区域卷积网络在阴影环境目标检测上的研究与应用(下)

目录 5.2 阴影检测模块与街景检测模块实验设置 5.2.1 实验环境与工具 5.2.3 损失函数 5.2.4 实验具体流程 5.3 实验评估与对比 5.3.1 两类实验的评估标准 5.3.2 两类实验结果对比 阴影环境下街景目标检测系统的实现 6.1 系统概述 6.2 系统软硬件环境 6.3 功能模块设计 6.4 系统…

【OpenSSH漏洞修复】升级到openssh9.4p1版本

实战环境 操作系统:Centos7.9 openssh版本:7.4 重要的升级文件 使用rpm包升级 D:\Linux基线离线安装包\openssh9.4-升级包 的目录openssh-9.4p1-4.el7.x86_64.rpm openssh-clients-9.4p1-4.el7.x86_64.rpm openssh-server-9.4p1-4.el7.x86_64.rpm需要自己去官网下载离线rp…

自定义子组件的v-model

一、传统的父子传参 作为前端程序员&#xff0c;我们在开发时&#xff0c;用到最多的就是父子传参了吧&#xff0c;这一点相信大家都很熟悉了&#xff0c;在这里简单的说一下 1.父传子 &#xff08;1&#xff09; 在父组件中引入子组件&#xff0c;并在父组件的components中注…