C++ | 四、指针、链表

news2024/9/28 9:26:55

指针

  • 指针用来储存地址
  • 定义方式,int *ptr;,使用*来表示所定义的变量是指针
  • 取地址符,ptr = &a;,通过&来取得一个普通变量的地址,并储存到指针中
  • 取值(解引用),想要取得一个指针变量所指向地址里储存的值,也是使用符号*,如b = *ptr即会把指针变量ptr存储地址里对应的值赋给b
  • 指针和数组的关系,实际上,数据结构就是基于指针设计的,例如数组int arr[2] = {1, 2};,其数组名arr实际上是一个存储了数组第一个元素地址的指针,比如可以使用int *ptr = arr;来把数组首元素的地址赋值给ptr
  • 指针的加减,指针可以通过加减来读取当前地址的相邻地址,并在使用取值符*(解引用)后可以读取相邻地址里的值,如int data = *(ptr + 2);
  • 空地址,C++中,使用一个特殊的字符nullptr用来表示当前指针不指向任何有效的内存地址,如int *ptr = nullptr;

链表基础知识

  • C++中为什么要使用链表结构
    • 可以充分利用小块的内存空间:因为诸如数组等数据结构,其必须占据一片连续的内存空间,此时如果数据量较大,则一些小内存空间就无法被利用,造成空间浪费;链表在内存中不连续储存,因此可以充分利用内存空间,具体见后面关于链表存储方式的介绍
    • 大小可变:数组不可变大小,因此不够灵活,而链表可以方便的进行增删等操作
    • 增删元素效率高:其它很多数据结构中,以增加元素为例,在增加之后,需要把后续所有元素都进行挪位,此时将严重影响效率,如图;而链表就没有这个问题,只需要改变所增加节点和其前一个节点,就可以完成增加元素的操作
    • 然而,链表也有缺点,就是查询效率低。这是因为链表中想要得到某一个节点的值,那就必须从前序节点依次寻址知道找到该节点
      • 其它数据结构增删效率低
  • 链表的结构:链表由多个节点组成,每个节点包括数据域data和指针域next,分别存储当前节点的数据和下一节点的地址
    • 链表的结构
    • 链表的第一个节点称为头节点head,在C++中,为了简化链表的插入和删除元素操作,通常在头节点前添加一个虚拟头节点dummyNode(可以不添加该虚拟头节点),该虚拟节点的data可以为空,但是next指针指向头节点的地址
    • 最后一个节点的next为nullptr
  • 链表的不同类型
    • 单链表,前面所提到的就是单链表,即单向链表,每个节点只存储下一节点的地址
    • 双链表,即双向链表,每个节点除了next指向下一节点外,还有prev指向上一节点,因此可以双向查询
      • 双链表
    • 循环链表,即头尾相接,也就是最后一个节点的next存储了头节点的地址(这种链表可以用来解决约瑟夫环的问题)
      • 循环链表
  • 链表的存储方式
    • 链表中的各个节点通过指针互相关联,因此不需要连续存储,具体的分配机制依不同的操作系统的内存管理机制而定
      • 链表的存储方式

链表节点结构体(struct)的自定义

  • 结构体struct可以用来自定义用户想要的数据类型,其地位等价于int、float、double这些数据类型(下面有一个结构体示例ListNode)
    • 结构体可以组合多种数据类型,如整型、浮点型、其它结构体等等
    • 定义一个结构体即一种新的数据类型之后,就可以使用该数据类型定义变量了
    • 定义的时候有多种初始化方式,常见的一种是使用构造函数。构造函数也是一种函数,但是它没有返回类型和返回值,另外它和结构体的名称相同,例如对于下面定义的这个ListNode结构体,其构造函数可以写为ListNode(int x) : val(x), next(nullptr) {},这里int x是形参,: val(x), next(nullptr)是一种初始化写法,冒号表示初始化列表的开始,后面表示val被赋值为x,next被赋值为nullptr
struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(nullptr) {}  // 节点结构的构造函数
};

链表的操作

  • 删除节点
    • 将所删除节点上一节点的next指向所删除节点的下一节点即可
    • 在C++中,由于内存需要自己管理,因此最好把所删除节点的内存手动释放掉
    • 删除节点
  • 添加节点
    • 只要把所添加节点位置的上一节点指向所添加节点,再把所添加节点的next指向下一节点即可
    • 添加节点

时间复杂度性能分析

  • 可以看到,上面添加和删除节点操作本身的时间复杂度为O(1),但是要找到对应的节点位置(即查询)的时间复杂度为O(n),因此链表适用于需要频繁增删但是较少查询的场景
  • 性能对比
  • 有关时间复杂度更具体的介绍见我的另一篇文章

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

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

相关文章

软件测试|Beautiful Soup库详细使用指南

简介 Beautiful Soup是一款强大的Python库,广泛用于解析HTML和XML文档,从中提取数据并进行处理。它的灵活性和易用性使得数据抽取变得简单,本文将详细介绍Beautiful Soup库的基本用法和示例。 安装Beautiful Soup 首先,需要确保…

一文详解JAVA的字节流,BufferedReader和BufferedWriter

目录 一、什么是Java的字节流 二、BufferedReader介绍 三、BufferedWriter介绍 一、什么是Java的字节流 Java的字节流是一种用于处理二进制数据的输入输出流。在Java中,字节流以字节为单位进行读取和写入操作。字节流分为输入字节流和输出字节流。 输入字节流&…

springCloude中Eureka模拟搭建集群

开三个不同端口号的服务, 而且还得模拟出三个不同的ip,由于时本机,所以只能去做三个本地域名,不要乱来,弄不好会出事的! eureka8886.com eureka8887.com eureka8888.com 这个是eureka的集群模块。 提供模块&#xff0…

Redis图形界面闪退/错误2系统找不到指定文件/windows无法启动Redis/不是内部或外部命令,也不是可运行的程序

Redis图形界面闪退/错误2系统找不到指定文件/windows无法启动Redis/不是内部或外部命令,也不是可运行的程序 我遇到了以上的问题。 其实,最重要的原因是我打开不了another redis desktop mannager,就是我安装了之后,无法打开它…

FFmpeg解决视频播放加载卡顿问题(FFmpeg+M3U8分片)

FFmpeg解决视频播放加载卡顿问题(FFmpegM3U8分片) 在这静谧的时光里,我们能够更清晰地审视自己,思考未来的方向。每一步的坚实,都是对勇气的拥抱,每一个夜晚的努力,都是对未来的信仰。不要害怕独行,因为正是…

机器学习算法实战案例:时间序列数据最全的预处理方法总结

文章目录 1 缺失值处理1.1 统计缺失值1.2 删除缺失值1.3 指定值填充1.4 均值/中位数/众数填充1.5 前后项填充 2 异常值处理2.1 3σ原则分析2.2 箱型图分析 3 重复值处理3.1 重复值计数3.2 drop_duplicates重复值处理 3 数据归一化/标准化3.1 0-1标准化3.2 Z-score标准化 技术交…

使用Openssl生成Https免费证书以及Nginx配置

1 证书和私钥的生成 1.创建服务器证书密钥文件 server.key: openssl genrsa -des3 -out server.key 2048 输入密码,确认密码,自己随便定义,但是要记住,后面会用到。 2.创建服务器证书的申请文件 server.csr openssl r…

外包干了4年,废了···

有一说一,外包没有给很高的薪资,是真不能干呀! 先说一下自己的情况,大专生,19年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了&#xff0…

Linux的基础命令学习

pwd - 显示当前工作目录的路径 cd - 切换工作目录,ls - 列出当前目录的文件和子目录 rm - 删除文件或目录 mkdir - 创建新目录 rm - 删除目录 nano/vi - 编辑文本文件,按Enter键进入 之后按i键就可以进入写入模式 之后输入文字以后按Esc键与:q就不保…

【设计模式-05】Facade门面Mediator调停者 | Decorator装饰器 | Chain Of Responsibility责任链

Facade门面Mediator调停者 1、Facade门面图解 2、Mediator调停者 一般是系统内部相互交错,比如消息中间件(MQ)就是这种设计模式,对各个功能或系统之间进行解耦。 Decorator装饰器 1、问题 2、解决方案 Chain Of Responsibility责任链 一、例子场景 业…

(Java企业 / 公司项目)JMeter接口压测使用(保姆式手把手教会)

一. JMeter简介认识(重点是下面的使用方法) JMeter是一个开源的Java应用程序,由Apache软件基金会开发和维护,可用于性能测试、压力测试、接口测试等。 1. 原理 JMeter的基本原理是模拟多用户并发访问应用程序,通过发…

手把手教你如何搭建Spring本地编译环境

大家好,我是极客涛,不知道小伙伴有没有和我一样的情况,在阅读Spring源码时,只通过静态的代码阅读很难有更深刻的理解,所以建议通过写测试类进行debug的方式,对核心的代码进行运行时的状态调试,这…

2024年腾讯云服务器活动价格整理汇总,5年和三年选择

腾讯云服务器租用价格表:轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年,540元三年、2核4G5M带宽218元一年,2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月,云服务器CVM S5实例2核2G配置280.8元一年…

TLS握手流程分析

1.SSL/TLS 历史 HTTP 是明文传输的协议,可能受到第三方的攻击,非常不安全。因此才诞生 “HTTPS”。 这个 “S” 表示 SSL/TLS 协议,用公式说明:HTTPS HTTP SSL(TLS)。 其中 SSL 即安全套接层(Secure Sockets Layer&…

【开发篇】四、MAT堆内存分析(Memory Analyzer Tool)

文章目录 1、使用2、报错3、MAT支配树4、MAT内存泄漏的检测原理5、导出运行中系统的内存快照6、补充 1、使用 内存溢出后,分析泄露的思路是: 在OOM前,将整个堆内存保存成一个hprof文件MAT打开hprof文件,MAT自行分析可疑对象 添…

模拟器安装XPosed框架教程

Xposed框架下载(搞不懂就先看完本篇教程再下载) 99%的情况只需要下载里面的XPosed鸭就行了 安卓8及以下XPosed框架 - 多开鸭模拟器安装XPosed框架图文视频教程 关于本站XPosed框架的说明 XPosed框架(即XP框架),由rovo89开发。适用于安卓7以…

Kafka消费流程

Kafka消费流程 消息是如何被消费者消费掉的。其中最核心的有以下内容。 1、多线程安全问题 2、群组协调 3、分区再均衡 1.多线程安全问题 当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。 对于线程安全&…

HNU-算法设计与分析-实验4

算法设计与分析实验4 计科210X 甘晴void 202108010XXX 目录 文章目录 算法设计与分析<br>实验41 回溯算法求解0-1背包问题问题重述想法代码验证算法分析 2 回溯算法实现题5-4运动员最佳配对问题问题重述想法代码验证算法分析 3 分支限界法求解0-1背包问题问题重述想法…

OpenGL Assimp加载各类型模型(.obj、.fbx、.glb、.3ds)

1.简介 本博客以.glb格式为例&#xff0c;加载glb格式的3d模型&#xff0c;网上找了一圈&#xff0c;基本上都是根据OpenGL官方示例&#xff0c;加载.obj格式的3d模型。 下面以.obj和.glb格式的3D模型简单介绍一下。 常见的.obj格式的3D模型如下所示&#xff1a;纹理都已经被…

FineBI实战项目一(23):订单商品分类词云图分析开发

点击新建组件&#xff0c;创建订单商品分类词云图组件。 选择词云&#xff0c;拖拽catName到颜色和文本&#xff0c;拖拽cat到大小。 将组件拖拽到仪表板。 结果如下&#xff1a;