数据结构基础(基于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.mzph.cn/pingmian/26144.shtml

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

相关文章

假期已结束,大家都开始上班了吗

千行赏金APP&#xff1a;一站式悬赏任务平台详解 一、功能特点 千行赏金APP&#xff0c;作为一个综合性的悬赏任务平台&#xff0c;其功能特点突出&#xff0c;为用户提供了丰富的体验。首先&#xff0c;用户可以在平台上发布各类任务&#xff0c;如填写问卷、参与调研、试玩游…

MySQL高性能(MySQL锁)

MySQL性能系列 MySQL锁 前言1. 死锁机制2. 思维导图与锁划分介绍3. 粒度划分锁3.1. 全局锁3.2. 页级锁&#xff08;Page-level locking&#xff09;3.3. 表级锁&#xff08;Tables-level lock&#xff09;○ 共享锁&#xff08;表级&#xff09;○ 排他锁&#xff08;表级&…

【perl】环境搭建

1、Vscode Strawberry Perl 此过程与tcl环境搭建很类似&#xff0c;请参考我的这篇文章&#xff1a; 【vscode】 与 【tclsh】 联合搭建tcl开发环境_tclsh软件-CSDN博客 perl语言的解释器可以选择&#xff0c;strawberry perl。Strawberry Perl for Windows - Releases。 …

如何在Linux虚拟机服务器上配置和部署Java项目?

在Linux虚拟机上配置和部署Java项目&#xff0c;通常涉及以下步骤&#xff1a; 1. 准备Linux虚拟机 选择合适的Linux发行版 &#xff1a;根据项目需求和个人熟悉程度&#xff0c;选择如Ubuntu LTS、CentOS Stream或Debian等发行版。 安装虚拟机软件 &#xff1a;在宿主机&#…

VS 2019 @ Win10 C++ MFC 安装实践

1 打开卸载窗口&#xff1a; 选择Windwos 卸载 &#xff0c;笔者有多个版本&#xff0c;选择VS1019 现在算正式打开了VS 1019的卸载&#xff0c;注意千万别点确认&#xff0c;点击&#xff0c;取消&#xff0c;进入安装配置 点击&#xff0c;取消后&#xff0c;进入VS 的安装配…

[图解]建模相关的基础知识-08

1 00:00:01,650 --> 00:00:04,950 如果说&#xff0c;A乘BB乘A的话 2 00:00:06,350 --> 00:00:07,140 意味着什么 3 00:00:07,560 --> 00:00:08,420 A就等于B了 4 00:00:09,500 --> 00:00:10,680 只有两个相等 5 00:00:10,690 --> 00:00:13,360 它们的笛卡尔…

docker回顾--docker compose详细解释,安装,与常用命令

文章目录 Docker compose简介什么是Docker compose核心概念优势 安装常用命令总结 Docker compose简介 什么是Docker compose Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。它使得开发者可以使用一个单独的 YAML 文件来定义应用所需的所有服务、网络和卷&a…

行为树BehaviorTree

主要依托于BehaviorTree.CPP进行介绍。 1 基本概念 1.1 是什么与用来做什么 官网 https://www.behaviortree.dev/docs/learn-the-basics/BT_basics Unlike a Finite State Machine, a behavior Tree is a tree of hierarchical nodes that controls the flow of execution o…

乡村振兴的乡村基础设施建设:完善基础设施,提升乡村生活品质,打造宜居宜业的美丽乡村

摘要&#xff1a;乡村振兴是新时代中国特色社会主义“三农”工作的重要内容&#xff0c;而乡村基础设施建设作为乡村振兴的基石&#xff0c;对于提升乡村生活品质、打造宜居宜业的美丽乡村具有至关重要的意义。本文从乡村基础设施建设的必要性出发&#xff0c;分析了当前乡村基…

用GAN网络生成彩票号码

本文将详细解析如何使用生成对抗网络(GAN)来生成彩票号码。我们将介绍代码的每个部分,并给出详细注释,帮助读者理解整个过程。效果如下: 导入依赖 首先,我们需要导入所需的库。 import numpy as np import pandas as pd import torch import torch.nn as nn import t…

14年后 苹果终于推出iPad原生计算器应用

迄今为止&#xff0c;在WWDC 2024大会上&#xff0c;新增的计算器应用获得了最热烈的掌声。iOS 官方计算器应用程序终于要登陆大屏幕了。该功能利用额外的屏幕空间带来了公司无法在 iPhone 上实现的新功能。其中最大的亮点是新增了"数学笔记"功能。新增的功能可以帮你…

黑豹程序员 堆和栈

简单变量及作用域 main()   int x1; show ()   int x2 执行步骤&#xff1a; 第1步&#xff1a;main()函数是程序入口&#xff0c;JVM先执行&#xff0c;在栈内存中开辟一个空间&#xff0c;存放int类型变量x&#xff0c;同时附值1。 第2步&#xff1a;JVM执行show()函…

ZDH-智能营销-标签模块

目录 主题 项目源码 预览地址 安装包下载地址 标签模块 什么是标签 标签场景分类 标签设计 标签按照场景做了分类&#xff0c;但是运营人员需要感知到吗 标签按照场景做了分类&#xff0c;底层的计算引擎是否需要划分&#xff1f; 标签模块&#xff0c;是否需要涉及…

最新thinkphp5内核全开源女神赢口红H5公众号版第五版(100%可经营)

最新thinkphp5内核全开源女神赢口红H5公众号版第五版&#xff08;100%可经营&#xff09; 搭建教程 1、程序为thinkPHP5开发 php版本要求5.6&#xff01;不支持虚拟主机&#xff01; 2、上传程序到您的根目录&#xff01;导入m213.sql文件&#xff01;修改数据库配置文件app…

WordPress模板推荐

WordPress外贸主题 wordpress跨境电商独立站主题&#xff0c;wordpress外贸建站模板。 手机配件wordpress外贸网站模板 充电器、移动电源、手机膜、手机电池、手机壳、手机转接头等手机配件wordpress外贸网站模板。 毛巾WordPress外贸主题 毛巾、面巾、婴童毛巾、浴巾、方巾、…

2024 AEE | 风丘科技将亮相日本爱知国际会展中心——共同创造!

2024年名古屋汽车工程博览会&#xff08;Automotive Engineering Exposition 2024 NAGOYA&#xff09;将于7月17-19日在日本爱知县国际展示场&#xff08;Aichi Sky Expo&#xff09;开展。本展会是专门为活跃在汽车行业的工程师和研究人员举办的汽车技术展览&#xff0c;汇聚了…

Python办公MySQL(一):安装MySQL以及Navicat可视化工具(附送Navicat到期解决方法)

目录 专栏导读1、下载 MySQL Community Server2、安装3、安装Navicat4、连接刚刚安装的MySQL5、创建一个数据库方法1方法2 6、创建一张表方法1&#xff1a;准备一个test文件方法2&#xff1a; Navicat到期解决总结 专栏导读 &#x1f338; 欢迎来到Python办公自动化专栏—Pytho…

干货 | 2024元宇宙技术融合与新质生产力的创新实践(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT/WORD原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&#xff01;&#xff…

Craig Federighi 和 John Giannandrea 在 WWDC 上谈论苹果智能技术

WWDC 主题演讲结束后&#xff0c;苹果公司的克雷格-费德里吉&#xff08;Craig Federighi&#xff09;和约翰-吉安南德雷亚&#xff08;John Giannandrea&#xff09;坐下来&#xff0c;更深入地讨论了苹果智能公司在人工智能方面所做的努力&#xff0c;包括该公司是如何训练模…

三高系统的架构设计方案:高并发、高可用、高性能

文章目录 一、互联网系统三高概述1、互联网的三高2、高并发3、高可用4、高性能 二、高并发、高性能技术解决方案1、多高的并发才算高并发&#xff1f;2、水平扩展3、负载均衡思想4、缓存思想5、池化复用思想6、异步思想7、预处理-惰性更新思想8、分而治之思想 三、高可用技术解…