数据结构基础(基于c++)

数据结构基础(基于c++)

文章目录

  • 数据结构基础(基于c++)
    • 前言
      • 1. 递归、迭代、时间复杂度、空间复杂度
      • 2. 数据结构
    • 数组与链表
      • 1. 数组
      • 2. 链表
      • 3. 动态数组
      • 4. 数组与链表对比

前言

参考资料:Hello 算法 (hello-algo.com)

1 2

1. 递归、迭代、时间复杂度、空间复杂度

递归

使用迭代模拟递归

/* 使用迭代模拟递归 */
int forLoopRecur(int n) {// 使用一个显式的栈来模拟系统调用栈stack<int> stack;int res = 0;// 递:递归调用for (int i = n; i > 0; i--) {// 通过“入栈操作”模拟“递”stack.push(i);}// 归:返回结果while (!stack.empty()) {// 通过“出栈操作”模拟“归”res += stack.top();stack.pop();}// res = 1+2+3+...+nreturn res;
}

常见时间复杂度例子:常见时间复杂度类型

常见空间复杂度例子:常见空间复杂度类型

1、常数阶:常量、变量、对象
2、线性阶:数组、链表、栈、队列
3、平方阶:矩阵、图
4、指数阶:二叉树(满二叉树)
5、对数阶:分治算法

递归函数一分为二时,时间复杂度为O(2n), 例子:func(n-1)+func(n-2)

递归函数逐层减半时,时间复杂度为O(log2n),例子:func(n/2)

主流排序算法的时间复杂度通常为 𝑂(𝑛log⁡𝑛) ,例如快速排序、归并排序、堆排序等。

笔记

// 使用系统时间生成随机种子unsigned seed = chrono::system_clock::now().time_since_epoch().count();
// 随机打乱数组元素shuffle(nums.begin(), nums.end(), default_random_engine(seed));
//to_string()函数map[i] = to_string(i);

2. 数据结构

64位计算机数据类型大小(Java):

3
  • C 和 C++ 未明确规定基本数据类型的大小,而因实现和平台各异。上表遵循 LP64 数据模型,其用于包括 Linux 和 macOS 在内的 Unix 64 位操作系统。
  • 字符 char 的大小在 C 和 C++ 中为 1 字节,在大多数编程语言中取决于特定的字符编码方法,详见“字符编码”章节。
  • 即使表示布尔量仅需 1 位(0 或 1),它在内存中通常也存储为 1 字节。这是因为现代计算机 CPU 通常将 1 字节作为最小寻址内存单元。

内存对齐

对齐规则:

  1. 第一个成员在与结构体偏移量为0的地址处

  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍地址

    对齐数 = 编译器默认的对齐数与该成员大小的较小值

  3. 结构体总大小为最大对齐数(每个成员都有一个对齐数)的整数倍

    到底为什么要内存对齐?_哔哩哔哩_bilibili

    (含字幕)C++ 让你不再害怕内存和指针 其一_哔哩哔哩_bilibili

    【C++面试100问】第二十九问:请详细讲讲C和C++中的内存分配方式_哔哩哔哩_bilibili

    4.4 内存与缓存 * - Hello 算法 (hello-algo.com)

数字是以“补码”的形式存储在计算机中的

计算机内部的硬件电路主要是基于加法运算设计的

问题:哈希冲突、红黑树

数组与链表

1. 数组

4

索引本质上是内存地址的偏移量

访问:在数组中访问元素非常高效,我们可以在 𝑂(1) 时间内随机访问数组中的任意一个元素。(随机访问

插入:如果想在数组中间插入一个元素,则需要将该元素之后的所有元素都向后移动一位,之后再把元素赋值给该索引。

/* 在数组的索引 index 处插入元素 num */
void insert(int *nums, int size, int num, int index) {// 把索引 index 以及之后的所有元素向后移动一位for (int i = size - 1; i > index; i--) {nums[i] = nums[i - 1];}// 将 num 赋给 index 处的元素nums[index] = num;
}

删除:若想删除索引 𝑖 处的元素,则需要把索引 𝑖 之后的元素都向前移动一位。删除元素完成后,原先末尾的元素变得“无意义”了,所以我们无须特意去修改它。

/* 删除索引 index 处的元素 */
void remove(int *nums, int size, int index) {// 把索引 index 之后的所有元素向前移动一位for (int i = index; i < size - 1; i++) {nums[i] = nums[i + 1];}
}

数组的优缺点

数组存储在连续的内存空间内,且元素类型相同。这种做法包含丰富的先验信息,系统可以利用这些信息来优化数据结构的操作效率。

  • 空间效率高:数组为数据分配了连续的内存块,无须额外的结构开销。
  • 支持随机访问:数组允许在 𝑂(1) 时间内访问任何元素。
  • 缓存局部性:当访问数组元素时,计算机不仅会加载它,还会缓存其周围的其他数据,从而借助高速缓存来提升后续操作的执行速度。

连续空间存储是一把双刃剑,其存在以下局限性。

  • 插入与删除效率低:当数组中元素较多时,插入与删除操作需要移动大量的元素。
  • 长度不可变:数组在初始化后长度就固定了,扩容数组需要将所有数据复制到新数组,开销很大。
  • 空间浪费:如果数组分配的大小超过实际所需,那么多余的空间就被浪费了。

应用:数组典型应用

2. 链表

5 6

链表节点 ListNode 除了包含值,还需额外保存一个引用(指针)。因此在相同数据量下,链表比数组占用更多的内存空间

通常将头节点当作链表的代称

插入:假设我们想在相邻的两个节点 n0n1 之间插入一个新节点 P则只需改变两个节点引用(指针)即可,时间复杂度为 𝑂(1) 。

/* 在链表的节点 n0 之后插入节点 P */
void insert(ListNode *n0, ListNode *P) {ListNode *n1 = n0->next;P->next = n1;n0->next = P;
}

删除:在链表中删除节点也非常方便,只需改变一个节点的引用(指针)即可

/* 删除链表的节点 n0 之后的首个节点 */
void remove(ListNode *n0) {if (n0->next == nullptr)return;// n0 -> P -> n1ListNode *P = n0->next;ListNode *n1 = P->next;n0->next = n1;// 释放内存delete P;
}

访问:

/* 访问链表中索引为 index 的节点 */
ListNode *access(ListNode *head, int index) {for (int i = 0; i < index; i++) {if (head == nullptr)return nullptr;head = head->next;}return head;
}

查找:

/* 在链表中查找值为 target 的首个节点 */
int find(ListNode *head, int target) {int index = 0;while (head != nullptr) {if (head->val == target)return index;head = head->next;index++;}return -1;
}

应用:链表经典应用

3. 动态数组

vector

访问:用索引进行访问

插入与删除:

/* 清空列表 */
nums.clear();/* 在尾部添加元素,时间复杂度O(1) */
nums.push_back(1);
nums.push_back(3);
nums.push_back(2);
nums.push_back(5);
nums.push_back(4);/* 在中间插入元素,时间复杂度O(n) */
nums.insert(nums.begin() + 3, 6);  // 在索引 3 处插入数字 6,insert是在前一个位置插入元素/* 删除元素,时间复杂度O(n) */
nums.erase(nums.begin() + 3);      // 删除索引 3 处的元素

拼接:

/* 拼接两个列表 */
vector<int> nums1 = { 6, 8, 7, 10, 9 };
// 将列表 nums1 拼接到 nums 之后
nums.insert(nums.end(), nums1.begin(), nums1.end());

排序:

/* 排序列表 */
sort(nums.begin(), nums.end());  // 排序后,列表元素从小到大排列

用数组实现动态数组:用数组实现动态数组

4. 数组与链表对比

7

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

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

相关文章

MySQL 的故事:一场 SQL 语句的戏剧演绎

本文由 ChatMoney团队出品 第一幕&#xff1a;解析与优化 - “翻译官与谋士” SQL 解析器是第一个上场的角色&#xff0c;任务就是把 SQL 请求翻译成 MySQL 能听懂的语言。就像你点餐时&#xff0c;服务员得听懂你到底要什么菜。不然你说“我要一盘炒青菜”&#xff0c;结果服…

基于STM32和人工智能的智能小车系统

目录 引言环境准备智能小车系统基础代码实现&#xff1a;实现智能小车系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统4.4 用户界面与数据可视化应用场景&#xff1a;智能小车管理与优化问题解决方案与优化收尾与总结 1. 引言 随着机器人技术的发展&#xff0c;智能小…

烽宇团队走进社区,关爱老人、爱护环境,开展一系列公益活动

在这片城市的喧嚣与繁忙中,烽宇团队用实际行动展示了他们对社会的关爱与责任感。作为在科技和商业领域取得显著成就的团队,烽宇不仅专注于企业发展,还积极投身于社区公益活动,回馈社会。 关爱老人,温暖人心 社区中的老年人是社会的宝贵财富,他们的生活质量直接关系到社区的幸福…

【论文精读】树环水印Tree-Ring Watermarks:隐形且稳健的扩散图像的指纹

文章目录 一、文章概览&#xff08;一&#xff09;主要工作&#xff08;二&#xff09;相关工作 二、具体方法&#xff08;一&#xff09;威胁模型&#xff08;二&#xff09;树轮水印概述&#xff08;三&#xff09;构造树轮水印键&#xff08;四&#xff09;提取用于水印检测…

Spring中网络请求客户端WebClient的使用详解

Spring中网络请求客户端WebClient的使用详解_java_脚本之家 Spring5的WebClient使用详解-腾讯云开发者社区-腾讯云 在 Spring 5 之前&#xff0c;如果我们想要调用其他系统提供的 HTTP 服务&#xff0c;通常可以使用 Spring 提供的 RestTemplate 来访问&#xff0c;不过由于 …

口罩佩戴智能监测摄像机

智能监测摄像机在现代城市安全管理中扮演着关键角色&#xff0c;尤其是像口罩佩戴智能监测摄像机这样的设备&#xff0c;其应用正在日益扩展&#xff0c;对于公共卫生和安全至关重要。 这类摄像机利用先进的图像识别技术&#xff0c;能够实时监测人群中是否佩戴口罩。通过高精度…

python基础语法学习(工程向)-Stage3-数据可视化

json 是一种轻量的数据交互格式&#xff0c;可以按照json指定的格式去组织和封装数据&#xff0c;而本质上是一个带有特定格式的字符串。 功能 json是在各个编程语言中流通的数据格式&#xff0c;负责不同编程语言之间的数据传递和交互。 格式 json的格式要求较为严格&#…

[Cloud Networking] Layer3 (Continue)

文章目录 1. DHCP Protocol1.1 DHCP 三种分配方式1.2 DHCP Relay (中继) 2. 路由协议 (Routing Protocol)2.1 RIP (Routing Information Protocol)2.2 OSPF Protocol2.2.1 OSPF Area2.2.2 Route ID / DR / BDR2.2.3 LSA / OSPF 邻居表 / LSDB / OSPF路由表 2.3 BGP Protocol2.4…

交易中的群体行为特征和决策模型

本文基于人的行为和心理特征&#xff0c;归纳出交易中群体的行为决策模型&#xff0c;并基于这个模型&#xff0c;分析股价波浪运行背后的逻辑&#xff0c;以及投机情绪的周期变化规律&#xff0c;以此指导交易&#xff0c;分析潜在的风险和机会&#xff0c;寻找并等待高性价比…

Python大数据-电商商品详情数据分析【JD电商平台为例】

一、项目背景 网上购物已经成为大众生活的重要组成部分。人们在电商平台上浏览商品并购物&#xff0c;产生了海量的用户行为数据&#xff0c;用户对商品的详情数据对商家具有重要的意义。利用好这些碎片化、非结构化的数据&#xff0c;将有利于企业在电商平台上的持续发展&…

mysql分析常用锁

这里写自定义目录标题 1.未提交事物&#xff0c;阻塞DDL&#xff0c;继而阻塞所有同表的后续操作,查看未提交事务的进程2.存着正在进行的线程数据。3.根据processlist表中的id杀掉未释放的线程4.查看正在使用的表5.mysql为什么state会有waiting for handler commit6.什么情况导…

鸿蒙实现金刚区效果

前言&#xff1a; DevEco Studio版本&#xff1a;4.0.0.600 所谓“金刚区"是位于APP功能入口的导航区域&#xff0c;通常以“图标文字”的宫格导航的形式出现。之所以叫“金刚区”&#xff0c;是因为该区域会随着业务目标的改变&#xff0c;展示不同的功能图标&#xff…

快速压缩前端项目

背景 作为前端开发工程师难免会遇到需要把项目压缩成压缩文件来传送的情况&#xff0c;这时候需要压缩软件进行压缩文件处理 问题 项目中的依赖包文件非常庞大&#xff0c;严重影响压缩速度&#xff0c;即使想先删除再压缩&#xff0c;删除文件也不会很快完成 解决 首先要安…

Jmeter如何进行分布式测试

使用Jmeter进行性能测试时&#xff0c;有些同学问我如果并发数比较大(比如最近项目需要支持1000并发)&#xff0c;单台电脑的配置(CPU和内存)可能无法支持&#xff0c;怎么办就需要使用分布式压测 1.分布式原理&#xff1a; 1、Jmeter分布式测试时&#xff0c;选择其中一台作…

数据库复习——范式(Normal Form)

因为上课的时候一直在摸鱼没有听懂&#xff0c;所以复习的时候理解一下数据库中关于范式的相关知识点。涉及范式的定义&#xff0c;以及给定一个函数依赖集判断是那种范式的方法。 范式 迄今为止一共提出了 6 6 6 种范式&#xff0c;他们的关系是 5 N F ⊂ 4 N F ⊂ B C N F …

UE5 C++ 跑酷游戏练习 Part1

一.修改第三人称模板的 Charactor 1.随鼠标将四处看的功能的输入注释掉。 void ARunGANCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) {// Set up action bindingsif (UEnhancedInputComponent* EnhancedInputComponent CastChecked&…

UML详解

1.what is the UML UML 全称是 Unified Modeling Language&#xff08;统一建模语言&#xff09;&#xff0c;它以图形的方式来描述软件的概念 2.它存在的目的 UML 的目标是通过一定结构的表达&#xff0c;来解决现实世界到软件世界的沟通问题。 3.什么是模&#xff0c;…

Centos7安装自动化运维Ansible

自动化运维Devops-Ansible Ansible是新出现的自动化运维工具&#xff0c;基于Python 开发&#xff0c;集合了众多运维工具&#xff08;puppet 、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置 、批量程序部署、批量运行命令 等功能。Ansible…

【每日刷题】Day68

【每日刷题】Day68 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 451. 根据字符出现频率排序 - 力扣&#xff08;LeetCode&#xff09; 2. 最小的K个数_牛客题霸_牛客…

github连接报本地

一、创建GIthub账号 这里默认大家已经创建好了并且有加速器&#xff0c;能正常上网&#xff0c;然后才能进行下面的操作。 二、创建ssh公钥 网址&#xff1a;Sign in to GitHub GitHub Sign in to GitHub GitHub 进入下面的界面&#xff1a; 然后创建新的密钥 三、官方文…