基础数据结构(1):链表

    在学习算法时,发现用什么数据结构来存储数据是很重要的,所以学习数据结构也是必须的,先从基础数据结构:数组,字符串,链表,栈,队列,树,矩阵,邻接表,哈希表等,数组和字符串我们已经了解的很多了,所以我们从链表开始学习,了解什么是链表,链表存储数据的方式,以及如何对链表进行各种操作,如何用数组来模拟链表,如何用栈来做链表相关的题目。

1.何为链表

  由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。同时因为单链表是非随机的存储结构,即不能直接找到表中某个特定的结点。查找某个特定的结点时,需要从表头开始遍历,依次查找。

      我们再看链表是什么:

      链表其实是由一个个结点组成,每个结点之间通过链接更新串联起来,每个结点都有一个后继结点,最后一个结点的后继结点为空结点

     图中就是一个链表其中橙色结点被称为黄色结点的前驱结点,黄色结点被称为橙色结点的后继结点,链表其实有单向链表、双向链表、循环链表等,这里先只介绍单向链表。那既然结点存储数据,怎么找到后驱结点呢?下面一起来看看吧

2.链表结点的定义

typedef struct ListNode
{int data;struct ListNode* next;
}ListNode;

     这就是一个结点的定义,我们把一个结点看成一个结构体,其中data是数据域,可以是任意类型,而struct ListNode* next定义了一个指向ListNode结构体的指针,这个指针的地址是后继结点,将指向下一个结点,这就是指针域,如下图所示  

      下面看看具体怎么创建一个链表的结点

3.链表结点创建

ListNode* ListCreateNode(int data)
{ListNode* node=(List*)malloc(sizeof(ListNode));node->data=data;node->next=NULL;return node;
}

     我们先用malloc函数分配一块内存空间,用来存放ListNode即链表对象,将数据域置为函数传参data,将指针域置为NULL,代表这是一个孤立的链表结点,最后返回这个结点的指针。

4.虚拟头结点

     为了方便对链表进行操作,避免第一个结点无法操作的问题,我们往往会建立一个虚拟头结点,这个头结点上不存储数据,只是指向链表的第一个结点

ListNode* head=ListCreateNode(-1);

5.链表的创建及初始化

     单链表有两种:一种是带虚拟头结点的,一种不带虚拟头结点。总的来说,带头结点的单链表相对于不带头结点的单链表来说,更加方便对链表进行操作,所以很多时候我们都是用带头结点的单链表,这里我们也只用学习带头结点的即可

5.1初始化带头结点的单链表

void InitList(ListNode* head) {head=(ListNode*)malloc(sizeof(ListNode));head->next=NULL;
}

5.2创建带头结点的单链表

5.2.1头插法

         头插法顾名思义就是从链表开头插入,先插入的后输出,后插入的先输入,例如,我想创建一个链表(4,7,9),输出就是(9,7,4)。

ListNode* HeadInsert(ListNode* head) {initlist(head); //初始化int n;scanf_s("%d",&n);for(int i=0;i<n;i++) {ListNode* node = (ListNode*)malloc(sizeof(ListNode));int data;scanf_s("%d", &data);node->data = data;node->next = head->next;head->next = node;}return head;
}

5.2尾插法

     尾插法顾名思义就是从链表末尾开始插入,先插入的先输出,后插入的后输出

ListNode* TailInsert(ListNode* head) {initlist(head); //初始化ListNode* cur = (ListNode*)malloc(sizeof(ListNode));cur = head;int n,data;scanf_s("%d",&n);for(int i=0;i<n;i++) {ListNode* node = (ListNode*)malloc(sizeof(ListNode));scanf_s("%d", &data)node->data = data;node->next =NULL;cur->next = node;cur = cur->next; }return head;
}

6.链表基础操作 

     创建完链表之后,我们就要对链表进行操作了,常见的操作就是增删改查

6.1遍历操作

void PrintList(ListNode* head) {ListNode* cur = head->next;while (cur) {printf("%d ", cur->data);cur = cur->next;}printf("\n");
}

6.2求单链表的长度

int Length(ListNode* head) {ListNode* cur = head->next;int len = 0;while (cur) {len++;cur = cur->next;}return len;
}

6.3查找操作

6.3.1按值查找
ListNode* locateElem(ListNode* head, int data)
{ListNode* cur = head->next;while (cur && cur->data != data){cur = cur->next;}return cur;
}
6.3.2按位查找
ListNode* getElem(ListNode* head, int i)
{int j = 1;ListNode* cur = head->next;if (i == 0)return head;if (i < 1)return NULL;while (cur && j < i){cur = cur->next;j++;}return cur;
}

6.4插入操作

void Insert(ListNode* head, int i, int data)
{ListNode* pre = getElem(head, i - 1);ListNode* cur = (ListNode*)malloc(sizeof(ListNode));cur->data = data;cur->next = pre->next;pre->next = cur;
}

6.5删除操作

     将链表的第i个结点删除

void Delete(ListNode* head, int i) {if (i<1 || i>Length(head))return;ListNode* pre = getElem(head, i - 1);ListNode* cur = pre->next;pre->next = cur->next;free(cur);
}

6.6判空操作

bool Empty(ListNode* head) {if (head->next == NULL) {printf("Head is null\n");return true;}else {printf("Head is not null\n");return false;}
}

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

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

相关文章

利用虚继承解决菱形继承(钻石继承)的问题 学习笔记

菱形继承概念&#xff1a; 两个派生类继承同一个基类 又有某个类同时继承两个派生类 这种继承又被称为菱形继承&#xff0c;或者钻石继承 定义一个基类Animal&#xff0c;两个派生类Sheep、Camal&#xff0c;SheepCame继承于两个派生类 class Animal { public:int m_Age; }…

Bert-vits2-v2.2新版本本地训练推理整合包(原神八重神子英文模型miko)

近日&#xff0c;Bert-vits2-v2.2如约更新&#xff0c;该新版本v2.2主要把Emotion 模型换用CLAP多模态模型&#xff0c;推理支持输入text prompt提示词和audio prompt提示语音来进行引导风格化合成&#xff0c;让推理音色更具情感特色&#xff0c;并且推出了新的预处理webuI&am…

SpringMVC---详细介绍+使用

文章目录 什么是SpringMVC&#xff1f;使用SpringMVCSpringMVC创建和连接创建连接RequestMapping的基础使用 获取参数返回数据返回静态页面返回非页面的普通数据&#xff08;text/html&#xff09;返回JSON对象请求转发或者请求重定向 什么是SpringMVC&#xff1f; SpringMVC它…

【Spring】14 ApplicationEventPublisherAware 接口

文章目录 1. 简介2. 作用3. 使用3.1 创建并实现接口3.2 配置 Bean 信息3.3 创建启动类3.4 启动3.5 工作流程图 4. 应用场景总结 Spring 框架为开发者提供了丰富的扩展点&#xff0c;其中之一是 Bean 生命周期中的回调接口。本文将专注介绍一个与事件发布相关的接口 Applicatio…

【SQLite】SQLite数据库简单使用与Navicat安装-加密

Sqlite为免安装数据库&#xff0c;安装步骤总结&#xff1a; 官网下载Sqlit数据库&#xff0c;官网下载地址:https://www.sqlite.org/download.html 下载: sqlite-dll-win64-x64-3390400.zip或者32位sqlite-dll-win32 sqlite-tools-win-x64-3440200.zip或者32位sqlite-tools-wi…

Opencv入门五 (显示图片灰度值)

源码如下&#xff1a; #include <opencv2/opencv.hpp> int main(int argc, char** argv) { cv::Mat img_rgb, img_gry, img_cny; cv::namedWindow("Example Gray",cv::WINDOW_AUTOSIZE); cv::namedWindow("Example Canny", cv::WINDOW_…

若依vue前端 报错error:0308010C:digital envelope routines::unsupported一步到胃的解决方法

第一步: 直接打开package.json 第二步: 直接替换scripts的内容为下面的内容 "scripts": {"dev": "SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-service serve","build:prod": "SET NODE_OPTIONS--openssl-leg…

无源晶振电路中两端电阻和电容的作用

无源晶振电路中两端电阻和电容的作用是什么&#xff0c;今天晶发电子就详细讲讲&#xff0c;具体如下&#xff1a; 一、并联电阻的作用 配合IC内部电路组成负反馈、移相&#xff0c;使放大器工作在线性区。 并联降低谐振阻抗&#xff0c;使无源晶振易启动。 并联电阻取值大小…

【vCenter Converter】VMware vCenter Converter Standalone 理论, 下载与安装要求

目录 1. vCenter Converter 概述1.1 作用与特征&#xff08;1&#xff09;性能和可靠性&#xff08;2&#xff09;互操作性&#xff08;3&#xff09;管理 2. 下载 vCenter Converter Standalone3. 安装 vCenter Converter Standalone3.1 系统要求&#xff08;1&#xff09;支持…

文件消失但是有占用内存的恢复方法

文件消失但占用内存是一个常见的问题&#xff0c;通常是由于文件系统错误或病毒攻击引起的。在这种情况下&#xff0c;文件虽然从目录结构中消失&#xff0c;但它们仍然占用存储空间。本文将分析这一问题的原因&#xff0c;并探讨解决该问题的几种方法。 文件消失但占用内存的原…

android11-开机自启脚本

1. 编写myshell脚本 diff --git a/device/rockchip/rk356x/ok3568_r/myshell.sh b/device/rockchip/rk356x/ok3568_r/myshell.sh new file mode 100644 index 0000000000..c78b6d93bd --- /dev/nullb/device/rockchip/rk356x/ok3568_r/myshell.sh-0,0 1,4 #!/vendor/bin/shec…

抢先看!Salesforce Spring ‘24中的10个亮点功能!

Spring 24来临在即&#xff0c;Preview Orgs已上线。在Spring 24中&#xff0c;将会为管理员、开发人员和顾问带来更多新功能。在这片云计算的海洋里&#xff0c;一些亮点功能总能在Salesforce生态系统中引起强烈反响。本篇文章为学习者们盘点了Spring 24中的10个亮点功能&…

Vue项目搭建过程

Vue项目搭建过程 1、安装NodeJs 1.1 下载安装包 在 http://nodejs.cn/download/ 上下载64位安装包&#xff0c;然后进行安装&#xff0c;和普通软件的安装一样。 C:\Users\Administrator>node -v v16.13.1C:\Users\Administrator>npm -v 8.5.51.2 安装cnpm # 安装cn…

C语言,数组循环哪家好,指针or下标?

日常工作中&#xff0c;我们经常会用到循环遍历数组元素。不考虑只能使用某一特定方式的情况下&#xff0c;有人喜欢用数组下标遍历&#xff0c;有人则喜欢用指针遍历。那么这两者是否有性能差异呢&#xff1f; 我们先来看两个例子&#xff1a; 代码一 /* a.c */ #include &…

【QML】QML复制文件或文件夹,显示进度,多线程复制

1. 效果 可以显示复制文件和文件夹的进度 复制文件&#xff1a; bool copyFileFunc(QString _from, QString _to);复制文件夹&#xff1a;bool copyDirectoryFiles(const QString &_from, const QString &_to);举例&#xff1a; //复制文件copyhelper.copyFileToDir(&…

推荐12款好用的在线平面设计工具,让设计更简单

平面设计是图形表达和信息展示的重要手段&#xff0c;在游戏场景和角色造型、插画、广告制作等艺术设计领域有着重要的应用&#xff0c;如海报设计、包装设计等。 平面设计强调视觉传达&#xff0c;一般以图像、图形和文字等视觉元素为主要手段&#xff0c;通过排版、配色、构…

SpringBoot、Java AOP实现方式

SpringBoot、Java AOP实现方式 搭建项目环境 我这里直接使用Maven创建项目之后再pom.xml中导入包 Spring版本 如果你的版本有最新的&#xff0c;最简单的办法就是&#xff0c;将版本都换成统一的&#xff0c;因为发布时候都是每个版本统一发布的&#xff0c;如果出现不兼容的…

大模型讲座

盘古NLP大模型典型场景 千亿大模型训练难点和解决方案 训练状态不稳定&#xff08;经常训练中断等&#xff09; 解决1&#xff1a;对loss和梯度等多维状态实时监测。对数据、学习率、参数精度、模型梯度进行针对性调整和断点恢复。 调整学习率的代码如下。调整参数、梯度类似…

kali安装HTTrack报错Unable to locate package httrack

kali安装后&#xff0c;直接安装Httrack导致报错 Unable to locate package httrack &#xff08;这里因为解决了&#xff0c;无法重现&#xff0c;则使用错误的包httrackttttt&#xff09; 原因&#xff1a;安装kali后第一次使用系统&#xff0c;则应该运行update命令 sudo …

基于ssm省出口基地公共信息服务平台论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本n省出口基地公共信息服务平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞…