C++ | 四、指针、链表

指针

  • 指针用来储存地址
  • 定义方式,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.mzph.cn/news/625199.shtml

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

相关文章

【华为OD机试真题2023CD卷 JAVAJS】查找一个有向网络的头节点和尾节点

华为OD2023(C&D卷)机试题库全覆盖,刷题指南点这里 查找一个有向网络的头节点和尾节点 知识点图DFS搜索 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 给定一个有向图,图中可能包含有环,图使用二维矩阵表示,每一行的第一列表示起始节点,第二列表示终止节…

LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置

在排序数组中查找元素的第一个和最后一个位置 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(lo…

Java 线程

1. 实现多线程的 2 种方式 Oracle 官网的文档中给出了 2 种实现多线程的方式: 实现 Runnable 接口;继承 Thread 类。 以上两种方式都会调用 Thread.run() 方法,区别是: 实现 Runnable 接口,只是执行 Thread.run() …

【迅搜17】SCWS分词(二)自定义字典及分词器

SCWS分词(二)自定义字典及分词器 经过上篇文章的学习,相信大家对分词的概念已经有了更深入的了解了吧。我们也知道了,SCWS 是 XS 中的一个重要组成部分,但它也是可以单独拿出来使用的。而对于分词器来说,不…

【新】Unity Meta Quest MR 开发(一):Passthrough 透视配置

文章目录 📕教程说明📕配置透视的串流调试功能📕第一步:设置 OVRManager📕第二步:添加 OVRPassthroughLayer 脚本📕第三步:在场景中添加虚拟物体📕第四步:设置…

202406读书笔记|《沉睡的线条世界》——翻山越岭,只为与你分享点滴的快乐

《沉睡的线条世界》登登登Dn绘著,简简单单的小画,简简单单的线条,简简单单的语言,温馨又有一点暖心。 怎样的你都好,做最真实的自己。 部分节选如下: 愿你我永远有热情,永远能为生活的每一个小惊…

阳光抑郁症测试

大部分人对抑郁症的理解,就是每天无精打采,死气沉沉,可实际上,还有一种阳光抑郁症,完全不是这个样子。这种抑郁症的人,做事情非常有活力,魅力十足,给人感觉十分有自信,但…

快速排序【hoare版本】【挖坑法】【双指针法】(数据结构)

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均…

如何写年终汇报

每年最头疼的事儿就是写年终个人汇报(总结)。有时还有篇幅限制,疼上加疼。 根据个人经验和参考其他同事的汇报,做了一个简要的总结,方便以后写汇报使用。 个人汇报大的逻辑是:做了什么做的怎么样&#xff…

MySQL多表查询(改进版)

1.创建student和score表 mysql> CREATE TABLE student (-> id INT(10) NOT NULL UNIQUE PRIMARY KEY ,-> name VARCHAR(20) NOT NULL ,-> sex VARCHAR(4) ,-> birth YEAR,-> department VARCHAR(20) ,-> address VARCHAR(50)-> ); Query O…

242.【2023年华为OD机试真题(C卷)】螺旋数字矩阵(JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-螺旋数字矩阵二.解题思路三.题解代码Python题解…

SpringCloud Nacos服务注册中心和配置中心

一、什么是Nacos? 官方介绍是这样的: Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您实现动态服务发现、服务配置管理、服务及流量管理。 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Na…

用python批量实现文件夹中所有pdf转成图片并插入到一个word文件中

要实现这个任务,你需要使用Python的几个库:PyPDF2 用于处理PDF文件,python-docx 用于操作Word文件,PIL(或Pillow)用于处理图片。 首先,确保你已经安装了这些库。如果没有,你可以使用…

Java 方法以及在计算机内部的调用问题

修饰符 返回值类型 方法名( 形参列表 ){ 方法体代码(需要执行的功能代码) return 返回值; } 方法在内种没有先后顺序,但是不能把一个方法定义在另一个方法中。 方法的返回值类型写void(无返回申明)时,方法内不能使用return返回数…

Linux中放大字体

环境:VMware17Pro,Ubuntu22.04 在显示设置外观中只看到图标放大的调整,没看到字体大小设置 不按照常规设置,点开下面的辅助功能->大号文本(没有设置具体字号的选项,但是可以放大) 效果图如下…

day-10 删除排序链表中的重复元素

思路 先统计每个值出现的次数,然后将出现次数为一的节点链接为一个链表即可 解题方法 while(t!null){ //统计每个值出现次数 arr[t.val100]1; tt.next; } while(t!null&&arr[t.val100]!1) tt.next;//确定返回的头结点 ttt; while(t!null&&t.next…

项目解决方案:多个分厂的视频监控汇聚到总厂

目 录 1、概述 2、建设目标及需求 2.1 建设目标 2.2 需求描述 2.3 需求分析 3. 设计依据与设计原则 3.1 设计依据 3.2设计原则 1、先进性与适用性 2、经济性与实用性 3、可靠性与安全性 4、开放性 5、可扩充性 6、追求最优化的系统设备配置…

Zynq7020 使用 Video Processing Subsystem 实现图像缩放

1、前言 没玩过图像缩放都不好意思说自己玩儿过FPGA,这是CSDN某大佬说过的一句话,鄙人深信不疑。。。 目前市面上主流的FPGA图像缩放方案如下:1:Xilinx的HLS方案,该方案简单,易于实现,但只能用…

MySQL语句 | 使用DATE_FORMAT()对查询结果按日、周、月分组统计

文章目录 语法举个通用的例子 按照年月日进行分组统计举个通用的例子举个实际的例子 在MySQL中, DATE_FORMAT() 函数可用于将日期按照指定的格式进行格式化,也可用于对数据记录按照不同的时间维度进行分组 语法 DATE_FORMAT(date, format)其中&#xf…