数据结构-----【链表:基础】
链表基础
1、链表的理论基础
1)基础:
链表:通过指针串联在一起的线性结构,每个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一个节点的指针),最后一个指针域指向null(空指针的意思)。
链表的入口节点称为链表的头结点也就是head。

2)链表类型:
链表包括单链表、双链表、循环链表:
单链表:指针域只能指向节点的下一个节点。
双链表:既可以向前查询也可以向后查询。

循环链表:链表首尾相连,循环链表可以解决约瑟夫环的问题。

3)链表的存储方式:
数组在内存中是连续分布的,但是链表在内存中并不是连续分布的,链表通过指针域的指针连接在内存中的各个节点。例如:这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。

4)链表的定义:
这个单向链表中,正是因为我们定义了节点的构造函数,指明了可以把x丢给val,才可以在初始化的时候直接赋值。
//单链表
struct ListNode{int val;//数据ListNode* next;//指向下一个节点的指针ListNode(int x):val(x),next(NULL){} //节点构造函数
};
//为什么要自己写构造函数呢?c++可以自己生成构造函数
//通过自己定义构造函数初始化节点
ListNode* head = new ListNode(5);
//使用默认构造函数初始化节点,不能直接给变量赋值!!
ListNode* head = new ListNode;
head->val = 5;
5)链表的操作:
链表中要注意的就是是否更改原来指针!由项目引发的思考:不得不引入值传递和指针传递:
**传递值:**如果传递的是基本数据类型或结构体(而不是指针),则函数内对形参的修改不会影响外部的实际参数。
#include <stdio.h>void modifyValue(int x) {x = x + 1; // 修改的是 x 的副本,不会影响外部的实际参数
}int main() {int a = 5;modifyValue(a);printf("%d\n", a); // 输出 5,a 没有被修改return 0;
}
**传递指针:**如果传递的是指针,函数内对指针所指向的数据的修改会影响到外部的实际参数。但修改指针本身的值不会影响外部的指针。
#include <stdio.h>void modifyPointer(int* ptr) {*ptr = *ptr + 1; // 修改指针所指向的数据,会影响外部的实际参数ptr ++; // 修改指针本身的值,不会影响外部的实际参数
}int main() {int b = 10;int* p = &b;modifyPointer(p);printf("%d\n", *p); // 输出 11,p 所指向的数据被修改return 0;
}
-
递值时,函数内的修改不会影响外部的实际参数。
-
传递指针时,函数内对指针所指向的数据的修改会影响外部的实际参数,但修改指针本身的值不会影响外部的指针。
1.打印链表
为了保险起见,还是可以在函数里面用临时变量保存链表值:
void SlistPrint(ListNode *phead){ListNode *cur = phead;while(!cur){printf("%d->", cur->data);cur = cur-> next;}printf("NULL\n");
}
2.清空链表:
好家伙不传入**pehead就要报错:

//一个结点的定义
typedef struct ListNode{int val;ListNode* next;//ListNode(int x):val(x),next(NULL){};//重构函数
}ListNode;//因为要改变外部链表头的值,所以要传入**
//pphead 表示一个 ListNode 结构体的对象,而不是一个指针。在你的 SListClear 函数中,*pphead = NULL; 尝试将一个结构体对象设置为 NULL,这是不合法的。
//如果你的目的是通过函数清空链表并将外部传递的链表头指针设置为 NULL,你应该使用指向指针的指针,即 ListNode** pphead,并在函数内部通过解引用两次来修改外部传递的链表头指针的值。
void SListClear(ListNode **pphead)//**PPhead指向指针的指针
{ListNode *cur = *pphead;while(!cur){ListNode* temp = cur->next;free(cur);cur = temp;}*pphead = NULL;
}int main(){ListNode* head = (ListNode*)malloc(sizeof(ListNode));head->val = 1;head->next = (ListNode*)malloc(sizeof(ListNode));head->next->val = 2;head->next->next = NULL;SListClear(&head);//注意这里是&相当于 **head// 在这里 head 已经被设置为 NULL,链表被清空if (head == NULL) {printf("List is empty\n");}system("pause"); return 0;
}
3.创建结点:
typedef struct ListNode{int val;ListNode* next;ListNode(int x):val(x),next(NULL){};//重构函数 C++可以直接写重构函数
}ListNode;//等效于直接 ListNode* node = new ListNode(val);
ListNode* CreateListNode(int x){ListNode* NewNode = (ListNode*)malloc(sizeof(ListNode));ListNode->val = x;ListNode->next = NULL;return NewNode;
}
3.删除节点:
比如删除D节点:
首先将C节点的next指针指向E,然后再手动释放D节点(py有自己的内存回收机制,不用手动释放,但是c/c++最好手动释放)
特别注意:因为单链表的只能指向下一个节点,删除某个节点的时候指针是在这个节点前一个节点的位置的。

typedef struct ListNode{int val;ListNode* next;ListNode(int x):val(x),next(NULL){};
}ListNode;ListNode* delete(ListNode * node){if(node->next!=NULL && node->next->next!=NULL){node->next = node->next->next;}return node;
}
4、添加节点:
在C和D中添加节点,让C的指针域指向F,再把F的指针域指向D。(添加不需要释放内存)
链表的增添和删除都是O(1)操作,也不会影响到其他的节点,但是查找的时间复杂度可能是O(n)(一个一个next指针进行查找)。
typedef struct ListNode{int val;ListNode* next;ListNode(int x):val(x),next(NULL){};
}ListNode;ListNode* add(ListNode * node,int val){ListNode* tmp = new ListNode(val);temp->next = node->next;node->next = temp;return node;
}
4.数组和链表的对比

相关文章:
数据结构-----【链表:基础】
链表基础 1、链表的理论基础 1)基础: 链表:通过指针串联在一起的线性结构,每个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一个节点的指针),最后一个指针…...
如何在pycharm里面运行pytest用例
pycharm运行三种方式 1.以xx.py脚本方式直接执行,当写的代码里面没用到unittest和pytest框架时,并且脚本名称不是以test_开头命名的,此时pycharm会以xx.py脚本方式运行 2.当脚本命名为test_xx.py时,用到unittest框架,…...
Charles抓包工具踩坑记录
请添加图片描述 Charles抓包工具 证书问题 输入网址:chls.pro/ssl 第一个下载证书网址,会出现一直加载不出来,无法下载证书的情况 解决:选择下面save Charles Root。。。 2 证书在mac中禁止修改问题 解决也很简单,按照…...
【RabbitMQ实战】邮件发送(直连交换机、手动ack)
一、实现思路 二、异常情况测试现象及解决 说明:本文涵盖了关于RabbitMQ很多方面的知识点, 如: 消息发送确认机制 、消费确认机制 、消息的重新投递 、消费幂等性, 二、实现思路 1.简略介绍163邮箱授权码的获取 2.编写发送邮件工具类 3.编写RabbitMQ配置文件 4.生产者发起调用…...
python 笔试面试八股(自用版~)
1 解释型和编译型语言的区别 解释是翻译一句执行一句,更灵活,eg:python; 解释成机器能理解的指令,而不是二进制码 编译是整个源程序编译成机器可以直接执行的二进制可运行的程序,再运行这个程序 比如c 2 简述下 Pyth…...
《SpringBoot+Vue》Chapter04 SpringBoot整合Web开发
返回JSON数据 默认实现 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>在springboot web依赖中加入了jackson-databind作为JSON处理器 创建一个实体类对象…...
腾讯地图异步调用
<template><!-- 定义地图显示容器 --><div id"container"></div> </template><script setup>import { onMounted } from vue;const mapKeys import.meta.env.VITE_GLOB_TX_MAP_KEYS;function initMap() {// //定义地图中心点坐…...
通过docker overlay2 目录名查找占用磁盘空间最大的容器名和容器ID
有时候经常会有个别容器占用磁盘空间特别大, 这个时候就需要通过docker overlay2 目录名查找占用磁盘空间最大的容器名和容器ID: 1、 首先进入到 /var/lib/docker/overlay2 目录下,查看谁占用的较多 [rootPPS-97-8-ALI-HD1H overlay2]# cd /var/lib/doc…...
每周算法:有向图强连通分量
题目链接 受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果 A A A 喜欢 B B B, B B B 喜欢 C C C,那…...
基于RackNerd + CentOS 7 64 Bit + aaPanel 的那些事
本文涉及以下几个站点: RackNerd - Introducing Infrastructure Stability NameSilo - https://www.namesilo.com/ aaPanel - https://www.aapanel.com/ 遇到错误 Cannot find a valid baseurl for repo: base/7/x86_64 解决办法 一、切换 yum源 首先可以去…...
大数据期末复习——hadoop、hive等基础知识
一、题型分析 1、Hadoop环境搭建 2、hadoop的三大组件 HDFS:NameNode,DataNode,SecondaryNameNode YARN:ResourceManager,NodeManager (Yarn的工作原理) MapReduce:Map࿰…...
什么是客户体验自动化?
客户体验自动化是近年来在企业界备受关注的一个概念。那么,究竟什么是客户体验自动化呢?本文将为您详细解析这一话题,帮助您更好地理解并应用客户体验自动化。 我们要先明确什么是客户体验。客户体验是指客户在使用产品或服务过程中的感受和体…...
高效除氟:探索CH-87up树脂在氟化工废水处理中的应用
摘要 本研究旨在评估Tulsimer CH-87up树脂针对经钙镁预处理后的氟化工废水的深度处理效果。实验结果显示,CH-87up树脂能显著降低废水中的氟离子浓度,从43.4mg/L降至0.34mg/L,远低于行业排放标准的5mg/L。此外,该树脂表现出卓越的…...
【Git】LFS
什么是lfs Git 是分布式 版本控制系统,这意味着在克隆过程中会将仓库的整个历史记录传输到客户端。对于包涵大文件(尤其是经常被修改的大文件)的项目,初始克隆需要大量时间,因为客户端会下载每个文件的每个版本**。Gi…...
隐式转换的魔法:Scala中隐式转换的深度解析
隐式转换的魔法:Scala中隐式转换的深度解析 在Scala编程语言的丰富特性中,隐式转换是一个强大而微妙的工具。它允许开发者在不改变现有代码的情况下,扩展或修改类的行为。本文将深入探讨Scala中隐式转换的工作原理,并通过详细的代…...
外贸企业选择什么网络?
随着全球化的深入发展,越来越多的国内企业将市场拓展到海外。为了确保外贸业务的顺利进行,企业需要建立一个稳定、安全且高速的网络。那么,外贸企业应该选择哪种网络呢?本文将为您详细介绍。 外贸企业应选择什么网络? …...
Redis 7.x 系列【14】数据类型之流(Stream)
有道无术,术尚可求,有术无道,止于术。 本系列Redis 版本 7.2.5 源码地址:https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 常用命令2.1 XADD2.2 XRANGE2.3 XREVRANGE2.4 XDEL2.5 XLEN2.6 XREAD2.7 XG…...
(四)opengl函数加载和错误处理
#include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostream>void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);std::cout << width << &qu…...
RuoYi-Vue3不启动后端服务如何登陆?
RuoYi-Vue3不启动后端服务如何登陆?RuoYi-Vue3使用的前端技术栈 是:Vue3 + Element Plus + Vite。 github开源地址:https://github.com/yangzongzhuan/RuoYi-Vue3 前后的分离在线演示项目地址:https://vue.ruoyi.vip/ 这种方式是用若依提供的在线后端接口,可以在此基础上修…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
