数据结构--数组(详细分析)

目录

🍉引言

🍉数组

🍈数组的特性

🍈数组的优缺点

🍍优点:

🍍缺点:

🍈数组的声明与初始化

🍈数组的常见操作

🍍 插入操作

🍍删除操作

🍍查找操作

🍅线性查找:

🍅二分查找:

🍈数组的常见问题实现

🍍反转数组

🍍数组中的最大和最小元素

🍈演示

🍍插入操作

🍍删除操作

🍍反转数组

🍉总结


🍉引言

  • 数据结构是计算机科学的基石,它们为数据的组织、管理和存储提供了不同的方法和策略。在众多数据结构中,数组和字符串是最基本且常用的两种。本教学文章将详细分析数组与字符串的特性,展示两者的示例操作与问题实现,并通过图示演示实现问题的过程。

🍉数组

🍈数组的特性

数组是一种线性数据结构,它使用连续的内存空间存储相同类型的元素。数组的主要特点如下:

  1. 固定大小:数组在声明时必须指定大小,并且在大多数编程语言中,数组的大小在其生命周期内不可改变。
  2. 随机访问:数组支持通过索引进行快速随机访问,这使得数组在查找操作中的效率很高。
  3. 相同数据类型:数组中所有元素必须是相同的数据类型,这保证了数组的内存布局的紧凑性和一致性。
  4. 低级别存储:由于数组使用连续的内存空间存储数据,它们在内存管理和访问速度方面具有优势。

🍈数组的分类

🍍基本定义

  • 数组的空间复杂度通常为 O(n),其中 n 是数组的元素个数。具体来说,如果每个元素占用的空间是固定的(比如在C语言中的 int 类型占用4个字节),那么整个数组的空间复杂度就是元素个数乘以每个元素占用的空间。

🍍静态数组 vs 动态数组

🍅静态数组
  • 静态数组在编译时确定大小,一旦分配就不能改变大小。其空间复杂度为:O(n)其中 n 是数组的长度。
🍅动态数组
  • 动态数组(如C++中的 std::vector,Java中的 ArrayList)在运行时可以调整大小。当需要扩展时,通常会以一定比例(如2倍)增加大小。因此,动态数组的空间复杂度稍微复杂一些,考虑到了扩展时的额外开销。
  • 动态数组的平均空间复杂度仍然是 O(n),但在最坏情况下,当数组需要扩展时,空间复杂度会瞬间增加到 O(2n),即需要额外的空间来存储新的元素数组。

🍍内存分配的细节

🍅连续内存分配
  • 数组元素在内存中是连续存储的,这种方式的优点是访问速度快,但缺点是需要一次性分配大块连续的内存。在内存紧张或碎片化严重的情况下,可能会导致分配失败。
🍅空间浪费
  • 由于数组在创建时必须确定大小,如果预估不准确,可能会出现空间浪费或空间不足的情况。预分配过多会导致内存浪费,预分配过少则需要重新分配更大的数组,这样不仅增加了额外的内存开销,还可能影响性能。

🍍实际示例分析

假设我们有一个包含 1000 个整数的数组 int arr[1000];

  • 每个整数占用 4 个字节。
  • 数组总共占用的空间为 1000×4=40001000×4=4000 字节,即 4 KB。

🍍 动态数组的扩展分析

假设一个动态数组在初始分配时大小为 4,存储了4个元素后需要扩展到 8:

  1. 初始状态:大小为 4,占用 4×4=164×4=16 字节。
  2. 扩展到 8:需要分配新的内存块,占用 8×4=328×4=32 字节。

在扩展过程中,原有的4个元素需要复制到新的内存块,导致在扩展的瞬间,数组占用的空间为 16+32=4816+32=48 字节。

🍍总结

  • 静态数组:空间复杂度为 O(n),其中 n 是数组长度。
  • 动态数组:平均空间复杂度为 O(n),但由于扩展过程可能导致瞬时空间复杂度达到 O(2n)。

🍈数组的优缺点

🍍优点

  • 快速访问

    • 数组提供了快速访问元素的能力。由于数组元素在内存中是连续存储的,可以通过索引直接访问任意元素,时间复杂度为 �(1)O(1)。
  • 易于遍历

    • 数组的线性结构使得遍历非常方便,可以使用简单的循环结构(如for循环)访问所有元素。
  • 内存管理

    • 数组在内存中是连续分配的,这可以提高缓存命中率,从而加快访问速度。
  • 简单性

    • 数组的数据结构和操作(如插入、删除、访问)相对简单,容易理解和实现。

🍍缺点

  • 固定大小

    • 在大多数编程语言中,数组的大小在创建时必须确定,不能动态调整。如果预估不准确,要么浪费内存,要么导致空间不足。
  • 插入和删除效率低

    • 由于数组的元素是连续存储的,在中间位置插入或删除元素需要移动大量元素,时间复杂度为 �(�)O(n),这对性能有负面影响。
  • 内存浪费

    • 如果数组大小预估过大,会浪费内存;如果预估过小,又可能导致数组溢出,需重新分配更大的数组,增加了复杂性和时间开销。
  • 类型限制

    • 数组通常只能存储相同类型的数据,这限制了数组的灵活性。如果需要存储不同类型的数据,需要使用其他数据结构(如对象或元组)。

🍈数组的声明与初始化

在C语言中,可以通过以下方式声明和初始化数组:

#include <stdio.h>int main() {// 声明一个大小为5的整数数组int arr[5];// 初始化数组int arr2[5] = {1, 2, 3, 4, 5};// 打印数组元素for(int i = 0; i < 5; i++) {printf("%d ", arr2[i]);}return 0;
}

🍈数组的常见操作

🍍 插入操作

在数组中插入元素需要将插入位置之后的所有元素向后移动一位,以腾出位置:

#include <stdio.h>void insert(int arr[], int n, int pos, int value) {for(int i = n; i > pos; i--) {arr[i] = arr[i - 1];}arr[pos] = value;
}int main() {int arr[6] = {1, 2, 3, 4, 5};int n = 5;  // 当前数组元素数量int pos = 2; // 插入位置int value = 99; // 插入值insert(arr, n, pos, value);for(int i = 0; i <= n; i++) {printf("%d ", arr[i]);}return 0;
}

🍍删除操作

删除数组中的元素需要将删除位置之后的所有元素向前移动一位:

#include <stdio.h>void delete(int arr[], int n, int pos) {for(int i = pos; i < n - 1; i++) {arr[i] = arr[i + 1];}
}int main() {int arr[5] = {1, 2, 3, 4, 5};int n = 5; // 当前数组元素数量int pos = 2; // 删除位置delete(arr, n, pos);for(int i = 0; i < n - 1; i++) {printf("%d ", arr[i]);}return 0;
}

🍍查找操作

在数组中查找元素可以通过线性查找或二分查找(如果数组有序)来实现:

🍅线性查找:
#include <stdio.h>int linearSearch(int arr[], int n, int value) {for(int i = 0; i < n; i++) {if(arr[i] == value) {return i;}}return -1;
}int main() {int arr[5] = {1, 2, 3, 4, 5};int value = 3; // 查找值int index = linearSearch(arr, 5, value);if(index != -1) {printf("Element found at index %d\n", index);} else {printf("Element not found\n");}return 0;
}
🍅二分查找:
#include <stdio.h>int binarySearch(int arr[], int left, int right, int value) {while(left <= right) {int mid = left + (right - left) / 2;if(arr[mid] == value) {return mid;}if(arr[mid] < value) {left = mid + 1;} else {right = mid - 1;}}return -1;
}int main() {int arr[5] = {1, 2, 3, 4, 5};int value = 3; // 查找值int index = binarySearch(arr, 0, 4, value);if(index != -1) {printf("Element found at index %d\n", index);} else {printf("Element not found\n");}return 0;
}

🍈数组的常见问题实现

🍍反转数组

反转数组意味着将数组中的元素顺序颠倒:

#include <stdio.h>void reverseArray(int arr[], int n) {int start = 0;int end = n - 1;while(start < end) {int temp = arr[start];arr[start] = arr[end];arr[end] = temp;start++;end--;}
}int main() {int arr[5] = {1, 2, 3, 4, 5};reverseArray(arr, 5);for(int i = 0; i < 5; i++) {printf("%d ", arr[i]);}return 0;
}

运行结果:

🍍数组中的最大和最小元素

查找数组中的最大和最小元素:

#include <stdio.h>void findMaxMin(int arr[], int n, int *max, int *min) {*max = arr[0];*min = arr[0];for(int i = 1; i < n; i++) {if(arr[i] > *max) {*max = arr[i];}if(arr[i] < *min) {*min = arr[i];}}
}int main() {int arr[5] = {1, 2, 3, 4, 5};int max, min;findMaxMin(arr, 5, &max, &min);printf("Max: %d, Min: %d\n", max, min);return 0;
}

运行结果:

🍈演示

🍍插入操作

在数组 arr = [1, 2, 3, 4, 5] 中插入值 99 到位置 2

初始数组: [1, 2, 3, 4, 5]
插入值99到位置2:
向后移动: [1, 2, 3, 3, 4, 5]
向后移动: [1, 2, 2, 3, 4, 5]
插入完成: [1, 99, 2, 3, 4, 5]

🍍删除操作

在数组 arr = [1, 2, 3, 4, 5] 中删除位置 2 的元素:

初始数组: [1, 2, 3, 4, 5]
删除位置2的元素:
向前移动: [1, 2, 4, 4, 5]
向前移动: [1, 2, 4, 5, 5]
删除完成: [1, 2, 4, 5]

🍍反转数组

将数组 arr = [1, 2, 3, 4, 5] 反转:

初始数组: [1, 2, 3, 4, 5]
反转过程:
交换位置0和4: [5, 2, 3, 4, 1]
交换位置1和3: [5, 4, 3, 2, 1]
反转完成: [5, 4, 3, 2, 1]

🍉总结

  • 数组作为一种固定大小且内存连续的线性数据结构,提供了高效的随机访问能力

 

希望这些能对刚学习算法的同学们提供些帮助哦!!!

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

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

相关文章

Touch Camera PRO 2024 Easy Mobile Desktop Camera Controller(触控相机专业版)

一个真正易于使用的移动+台式摄像机控制器,具有视角切换功能! Touch Camera PRO 是一款非常易于使用的移动+桌面相机控制器,具有透视切换功能!它在 Home Designer、Runtime Level Editor 和 Floor Map Designer 等其他插件中使用! 在桌面和移动设备上工作! 一个干…

WIireShark使用教程

文章目录 目录 文章目录 一.入门抓包示例 一.入门抓包示例 先介绍一下如何使用wireshark抓取相应网卡的流量&#xff0c;让读者可以先上手操作感受一下抓包的具体过程。 1.打开wireshark的主界面如下 2.选择需要抓包的网卡&#xff0c;鼠标左键双击&#xff0c;即可抓取该网…

Mysql常见问题总结

1、MySQL初始化报错 mysqld --initialize --usermysql --console 2024-06-02T15:52:22.645557Z 0 [System] [MY-013169] [Server] D:\installSoft\mysql-8.0.21-winx64\bin\mysqld.exe (mysqld 8.0.21) initializing of server in progress as process 8980 2024-06-02T15:52:2…

量子加速超级计算简介

本文转载自&#xff1a;量子加速超级计算简介(2024年 3月 13日) By Mark Wolf https://developer.nvidia.cn/zh-cn/blog/an-introduction-to-quantum-accelerated-supercomputing/ 文章目录 一、概述二、量子计算机的构建块&#xff1a;QPU 和量子位三、量子计算硬件和算法四、…

【IC验证】一文速通多通道数据整型器(MCDF)

目录 01 README 02 MCDF设计结构 2.1 功能描述 2.2 设计结构 2.3 接口与时序 2.3.1 系统信号接口 2.3.2 通道从端接口 2.3.3 整形器接口 2.3.4 控制寄存器接口 2.3.4.1 接口时序图 2.3.4.2 各数据位信息 03 验证框图 3.1 reg_pkg 3.1.1 reg_trans 3.1.2 reg_driv…

【一刷《剑指Offer》】面试题 27:二叉搜索树与双向链表

牛客对应题目链接&#xff1a;二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com) 力扣对应题目链接&#xff1a;LCR 155. 将二叉搜索树转化为排序的双向链表 - 力扣&#xff08;LeetCode&#xff09; 一、《剑指 Offer》对应内容 二、分析题目 上面力扣上的这道题目和牛客…

AGM DAP-LINK 离线烧录报错信息分析

DAP-LINK 支持离线烧录。 即&#xff1a;先把要烧录的bin 烧录到DAP-LINK 中&#xff1b;然后DAP-LINK 可以脱离PC&#xff0c;上电后通过按键对目标板进行烧录。 CMSIS-DAP模式 跳线JGND断开&#xff0c;状态LED D4快闪&#xff0c;D3常亮&#xff08;串口状态&#xff09;。…

接口设计的最佳实践-下篇

大多数程序员&#xff0c;做得最多的事&#xff0c;也不过是写接口这件事而已。 今天继续总结下接口设计需要注意的点。尽量每种都给出具体的场景、案例等&#xff0c;希望大家能有所收获。 1、接口幂等 幂等性&#xff1a;是指一个操作或者一个服务&#xff0c;无论执行多少…

Vue3 - Mac系统用文本编辑写html不显示效果的坑

平时在win系统下&#xff0c;可以直接对文本进行编辑&#xff0c;非常的舒服。 在mac系统中&#xff0c;也有类似的功能&#xff0c;就是文本编辑&#xff0c;没想到居然还有坑。 这是我mac系统中创建的html文件&#xff0c;想着没有几行代码&#xff0c;就没有开编辑器了&am…

C语言 | Leetcode C语言题解之第125题验证回文串

题目&#xff1a; 题解&#xff1a; bool isalumn(char c) {return (c > a && c < z) || (c > A && c < Z) || (c > 0 && c < 9); }bool isPalindrome(char* s) {for (int left 0, right strlen(s) - 1; left < right; left, …

【传知代码】多视图3D目标检测位置嵌入变换(论文复现)

前言&#xff1a;三维目标检测技术正逐渐成为计算机视觉领域的重要研究方向。特别是在自动驾驶、增强现实&#xff08;AR&#xff09;、虚拟现实&#xff08;VR&#xff09;以及机器人导航等应用中&#xff0c;对三维空间内目标的精准检测与定位显得尤为重要。然而&#xff0c;…

SAP_SD模块-销售交货并开票后发现物料没维护价格的完整处理方法(含POD功能)

销售流程完结后&#xff0c;发现物料价格没维护时&#xff0c;如何处理 一、业务背景&#xff1a; 1、问题发现时间&#xff1a;2024年6月2日&#xff1b; 2、问题描述&#xff1a; 2024年5月份的单据业务存在交货成本和开票成本为0的单据&#x…

PyCharm如何更换解析器为Anaconda,如何自己切换python环境

自己使用了Anaconda创建了一个环境&#xff1a; 如何在工具PyCharm中切换自定义的python环境呢&#xff1f; 1. 点击 设置 2. 项目&#xff1a;python - Python解析器 此时会发现&#xff0c;只有一个默认的版本。 3. 点击 添加解析器 - 添加本地解析器 4. 选择 conda 环境…

AI智能语音机器人系统如何对接科大讯飞接口

关于AI语音机器人的介绍有很多&#xff0c;但是由于商业化&#xff0c;没有一个能真正说明白的&#xff0c;当然&#xff0c;我们搭建的AI智能机器人系统也是商业化的&#xff0c;毕竟业务是做这方面的&#xff0c;但是价格绝对是公道的&#xff0c;废话不多说了&#xff0c;我…

Qt各发布版本介绍与选择

一.Qt各个主要版本介绍 1.Qt4 Qt4的第一个版本是Qt 4.0&#xff0c;发布于2005年6月1日。 Qt 4的最后一个版本是Qt 4.8.7&#xff0c;发布时间是2015年6月10日。 2.Qt5 &#xff08;1&#xff09;Qt5的第一个版本是Qt 5.0&#xff0c;发布于2012年12月19日。 &#xff08;2&…

ubuntu安装notion

一、背景&#xff1a; 不用windwos系统&#xff0c;完全可以&#xff0c;然后基本软件都有&#xff0c;怎么安装notion呢 二、步骤 1. 更新源 echo "deb [trustedyes] https://apt.fury.io/notion-repackaged/ /" | sudo tee /etc/apt/sources.list.d/notion-repa…

基于字典树可视化 COCA20000 词汇

COCA20000 是美国当代语料库中最常见的 20000 个词汇&#xff0c;不过实际上有一些重复&#xff0c;去重之后大概是 17600 个&#xff0c;这些单词是很有用&#xff0c;如果能掌握这些单词&#xff0c;相信会对英语的能力有一个较大的提升。我很早就下载了这些单词&#xff0c;…

基于Django的博客系统之用HayStack连接elasticsearch增加搜索功能(五)

上一篇&#xff1a;搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL&#xff08;四&#xff09; 下一篇&#xff1a;基于Django的博客系统之增加类别导航栏&#xff08;六&#xff09; 功能概述 添加搜索框用于搜索博客。 需求详细描述 1. 添加搜索框用于搜索博客 描…

【数据密集型系统设计】软件系统的可靠性、可伸缩性、可维护性

文章目录 一. 数据密集型程序的特点以及遇到的问题二. 可靠性 : 即使出现问题&#xff0c;也能继续正确工作1 硬件故障2. 软件错误3. 人为错误 二. 可伸缩性1. 描述负载与推特的例子2. 描述性能-延迟和响应时间3. 应对负载的方法 四. 可维护性1. 可操作性&#xff1a;人生苦短&…

Chromebook Plus中添加了Gemini?

Chromebook Plus中添加了Gemini&#xff1f; 前言 就在5月29日&#xff0c;谷歌宣布了一项重大更新&#xff0c;将其Gemini人工智能技术集成到Chromebook Plus笔记本电脑中。这项技术此前已应用于谷歌的其他设备。华硕和惠普已经在市场上销售的Chromebook Plus机型&#xff0c;…