从0开始学C++ 第二十七课 数据结构入门 - 数组与链表

第二十七课:数据结构入门 - 数组与链表

学习目标:

  1. 理解数组的基本概念和操作。
  2. 掌握链表的基本结构与特点。
  3. 学会在C++中定义和操作数组和链表。
  4. 了解数组和链表的基本使用场景。

学习内容:

  1. 数组(Array)

    • 概念:数组是一种线性数据结构,用一段连续的内存空间来存储一系列相同类型的元素。
    • 参数用法:
      • 索引(Index):数组中每个元素的位置,通常从0开始。
      • 长度(Length):数组中元素的数量,确定数组大小的属性。
    • 代码示例:
      #include <iostream>
      using namespace std;int main() {int arr[5] = {1, 2, 3, 4, 5}; // 声明并初始化一个整型数组// 访问并打印数组元素for (int i = 0; i < 5; i++) {cout << "Element at index " << i << ": " << arr[i] << endl;}return 0;
      }
      
    • 预计输出效果:
      Element at index 0: 1
      Element at index 1: 2
      Element at index 2: 3
      Element at index 3: 4
      Element at index 4: 5
      
    • 使用场景:数组通常用于存储固定数目的元素,适合快速地通过索引查询元素。
  2. 链表(LinkedList)

    • 概念:链表是一种线性结构,由一系列不必在内存中连续存储的元素组成,每个元素均包含数据部分和指向下一个元素的指针。
    • 参数用法:
      • 节点(Node):链表中的元素,包含数据和指向下一个节点的指针。
      • 头指针(Head):指向链表的第一个节点的指针。
    • 代码示例:
      #include <iostream>
      using namespace std;// 定义链表节点结构体
      struct Node {int data;Node* next;
      };// 打印链表函数
      void printList(Node* n) {while (n != nullptr) {cout << n->data << " ";n = n->next;}cout << endl;
      }int main() {Node* head = new Node();Node* second = new Node();Node* third = new Node();head->data = 1; // 赋值head->next = second; // 指向下一个节点second->data = 2;second->next = third;third->data = 3;third->next = nullptr;printList(head); // 打印链表return 0;
      }
      
    • 预计输出效果:
      1 2 3
      
    • 使用场景:链表适合于元素数量变动较大的情况,便于插入和删除元素,但访问特定位置的元素较慢。

链表遍历与插入

  1. 链表的遍历

    • 链表的遍历意味着按照链表的指针从头到尾访问每个节点。
    • 遍历通常使用循环或递归来完成。
  2. 链表中的数据插入

    • 链表中的数据可以在头部、尾部或任意给定节点后插入。
    • 插入操作需要更改节点的指针以维护链表的结构。

链表的节点定义示例(C++):

class ListNode {
public:int val;ListNode *next;ListNode(int x) : val(x), next(nullptr)};

遍历链表示例(C++):

void traverseList(ListNode* head) {ListNode* temp = head;while(temp != nullptr) {cout << temp->val << " ";temp = temp->next;}cout << endl;
}

链表中数据插入示例(C++):

  1. 在头部插入:
ListNode* insertAtHead(ListNode* head, int x) {ListNode* newNode = new ListNode(x);newNode->next = head;head = newNode;return head;
}
  1. 在尾部插入:
ListNode* insertAtTail(ListNode* head, int x) {ListNode* newNode = new ListNode(x);if(head == nullptr) {return newNode;}ListNode* temp = head;while(temp->next != nullptr) {temp = temp->next;}temp->next = newNode;return head;
}
  1. 在给定节点后插入:
void insertAfterNode(ListNode* prevNode, int x) {if(prevNode == nullptr) {cout << "The given previous node cannot be null." << endl;return;}ListNode* newNode = new ListNode(x);newNode->next = prevNode->next;prevNode->next = newNode;
}

练习题:

  1. 实现一个单链表,并定义一个函数遍历此链表。
  2. 写出一个函数,在单链表的头部插入一个节点。
  3. 写出一个函数,在单链表的尾部插入一个节点。
  4. 写出一个函数,在单链表的某个节点后插入一个新节点。
#include <iostream>class ListNode {
public:int val;ListNode *next;ListNode(int x) : val(x), next(nullptr)};class SinglyLinkedList {
public:ListNode *head;SinglyLinkedList() : head(nullptr)    // 遍历链表void traverseList() {ListNode *temp = head;while (temp != nullptr) {std::cout << temp->val << " ";temp = temp->next;}std::cout << std::endl;}// 在头部插入节点void insertAtHead(int x) {ListNode *newNode = new ListNode(x);newNode->next = head;head = newNode;}// 在尾部插入节点void insertAtTail(int x) {ListNode *newNode = new ListNode(x);if (head == nullptr) {head = newNode;} else {ListNode *temp = head;while (temp->next != nullptr) {temp = temp->next;}temp->next = newNode;}}// 在某个节点后插入新节点void insertAfterNode(ListNode *prevNode, int x) {if (prevNode == nullptr) {std::cout << "The given previous node cannot be null." << std::endl;return;}ListNode *newNode = new ListNode(x);newNode->next = prevNode->next;prevNode->next = newNode;}
};int main() {SinglyLinkedList list;// 在链表头部插入节点list.insertAtHead(5);list.insertAtHead(3);list.insertAtHead(1);// 在链表尾部插入节点list.insertAtTail(7);list.insertAtTail(9);// 遍历链表list.traverseList();// 在链表中第一个节点后插入新节点list.insertAfterNode(list.head, 2);// 再次遍历链表list.traverseList();return 0;
}

目录
第二十八课 数据结构深入 - 栈和队列

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

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

相关文章

js vue调用activex ocx

js vue调用activex ocx 与IE调用方式不同处 CLSID和TYPE <OBJECT id"MultiplyDemo" refocx1 CLSID"{8EEF7302-1FC8-4BA0-8EA5-EC29FDBCA45B}" TYPE"application/x-itst-activex" width15% height15%></OBJECT>//调用方式1 //或是 …

品牌价值的累积与倍增:指数函数的含义及其在企业运营中的应用

品牌的价值日益凸显。品牌价值的累积与倍增不仅是企业追求的目标&#xff0c;也是市场竞争的重要标志。指数函数作为一种数学模型&#xff0c;对于描述品牌价值的增长具有重要意义。本文将深入探讨指数函数的含义及其在企业运营中的应用&#xff0c;并分析如何通过持续创新、品…

【DevOps】Jenkins Extended E-mail 邮件模板添加自定义变量

文章目录 1、配置Jenkins邮箱2、配置告警模板1、配置Jenkins邮箱 略 2、配置告警模板 自定义变量:DYSK_PYTEST_STATUS // Uses Declarative syntax to run commands inside a container. pipeline {agent {kubernetes {cloud "kubernetes" //选择名字是kuberne…

绘制PCB封装库的神器

我们平时绘制PCB封装时&#xff0c;一般都是按照元器件数据表上的封装图来绘制&#xff0c;有一些ECAD软件提供了向导&#xff0c;但是这个过程还是比较繁琐。现在有很多大厂比如TI都会提供芯片封装库&#xff0c;一般需要Ultra Librarian软件才能打开&#xff0c;然后再转换成…

【ZYNQ入门】第十篇、基于FPGA的图像白平衡算法实现

目录 第一部分、关于白平衡的知识 1、MATLAB 自动白平衡算法的实现 1.1、matlab代码 1.2、测试效果 1.3 测试源图 2、为什么摄像头采集的图像要做白平衡 3、自动白平衡算法总结 4、FPGA设计思路 4.1、实时白平衡的实现 4.2、计算流程优化思路 第二部分、硬件实…

如何查看Linux CPU占有率

目录 1、top 2、htop 3、vmstat 4、mpstat 5、iostat 查看嵌入式设备CPU占有率是评估系统资源使用情况的重要方式。 在Linux系统中&#xff0c;有多种方法可以查看CPU占有率&#xff0c;这里介绍几种常用的命令行工具。 1、top 这是最常用的命令之一&#xff0c;它提供了…

LeetCode-题目整理【3】:买卖股票的最佳时机

买卖股票的最佳时机 都是求最大利润&#xff0c;但是在没有限制&#xff0c;如121和122&#xff0c;动态规划稍微复杂一些&#xff0c;建议不用&#xff0c;到最后两道难题&#xff0c;题目有限制&#xff0c;使用动态规划通过求解子问题的最优解来逐步求解原问题的最优解。 买…

C语言之反汇编查看函数栈帧的创建与销毁

文章目录 一、 什么是函数栈帧&#xff1f;二、 理解函数栈帧能解决什么问题呢&#xff1f;三、 函数栈帧的创建和销毁解析3.1、什么是栈&#xff1f;3.2、认识相关寄存器和汇编指令3.2.1 相关寄存器3.2.2 相关汇编命令 3.3、 解析函数栈帧的创建和销毁3.3.1 预备知识3.3.2 代码…

AI对比:ChatGPT和文心一言的区别和差异

目录 一、ChatGPT和文心一言大模型的对比分析 1.1 二者训练的数据情况分析 1.2 训练大模型数据规模和参数对比 1.3 二者3.5版本大模型对比总结 二、ChatGPT和文心一言功能对比分析 2.1 二者产品提供的功能情况分析 2.2 测试一下各种功能的特性 2.2.1 文本创作能力 2.2…

婴儿洗衣机怎么选?热门品牌希亦、觉飞、由利详细测评

宝宝的衣物是不是要和大人的衣服分开洗呢&#xff1f;这是很多新手爸妈都会遇到的一个问题。有的人认为&#xff0c;宝宝的衣服要单独洗&#xff0c;以免被大人的衣服上的细菌污染&#xff1b;有的人认为&#xff0c;宝宝的衣服可以和大人的衣服一起洗&#xff0c;这样可以节省…

优先级队列(堆)

目录 1 概念 2 堆的概念 2.1小根堆 2.2大根堆 3堆的存储方式​​​​​​​ 4、堆的创建 4.1堆向下调整 5、时间复杂度 6、堆的插入&#xff08;向上调整&#xff09; 7、堆的删除 8、PriorityQueue的特性 9、堆排序 1 概念 我们知道的队列&#xff0c;队列是一…

leetcode---Z字形变换

题目&#xff1a; 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "PAYPALISHIRING" 行数为 3 时&#xff0c;排列如下&#xff1a;之后&#xff0c;你的输出需要从左往右逐行读取&#xff0c;产生…

Nginx入门教程+案例

摘要&#xff1a;Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。本文将介绍 Nginx 的基本概念、安装方法、配置文件以及一些常见应用场景&#xff0c;并通过一个简单的案例展示 Nginx 的实际应用。 一、Nginx 基本概…

redis高可用之主从部署

文章目录 前言1. 同步以及命令传播1.1 同步1.2 命令传播 2. 解决从服务器断线重连2.1 解决方案 3. PSYNC命令4. 复制步骤1:设置主服务器的地址和端口步骤2:建立套接字连接 ——其实就是建立TCP连接步骤3:发送PING命令步骤4:身份验证步骤5:发送端口信息步骤6:同步步骤7:命令传播…

鸿蒙5.0发布时间已定!何处寻得移动开发加速器?

直接在百度上搜索「鸿蒙5.0发布时间」&#xff0c;出来的结果&#xff0c;那一个比一个焦虑~~ 百度的AI基于综合内容判断得出&#xff0c;鸿蒙5.0的发布时间在2023-04-17 百度知道推的答案是202年年4月中 但不管几月&#xff0c;“鸿蒙元年”似乎都是确定的&#xff0c;就是…

Linux切换jdk版本

参考文献&#xff1a;Linux 多个JDK的版本 脚本切换 - C小海 - 博客园 (cnblogs.com)

树莓派ubuntu:CSI接口摄像头安装驱动程序及测试

树莓派中使用OV系列摄像头&#xff0c;网上能搜到的文章资源太老了&#xff0c;文章中提到的摄像头配置选项在raspi-config中并不存在。本文重新测试整理树莓派摄像头的驱动安装、配置、测试流程说明。 libcamera 新版本中使用libcamera作为摄像头驱动程序。 libcamera是一个…

【计算机系统组成原理】操作系统处理器深入介绍

博主介绍&#xff1a;✌全网粉丝喜爱、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦&#xff01; &#x1f345;附上相关C语言版源码讲解&#x1f345; &#x1f44…

ZYNQ-7020 集成了运行NI Linux Real‑Time的实时处理器,支持FPGA二次开发

模拟和数字I/O&#xff0c;667 MHz双核CPU&#xff0c;512 MB DRAM&#xff0c;512 MB存储容量&#xff0c;Zynq-7020 FPGA CompactRIO Single-Board控制器 sbRIO‑9637是一款嵌入式控制器&#xff0c;在单块印刷电路板(PCB)上集成了运行NI Linux Real‑Time的实时处理器、用户…

RK3568 移植Ubuntu

使用ubuntu-base构建根文件系统 1、到ubuntu官网获取 ubuntu-base-18.04.5-base-arm64.tar.gz Ubuntu Base 18.04.5 LTS (Bionic Beaver) 2、将获取的文件拷贝到ubuntu虚拟机,新建目录,并解压 mkdir ubuntu_rootfs sudo tar -xpf u