【追求卓越01】数据结构--数组

引导

        这一章节开始,正式进入数据结构与算法的学习过程中。由简到难,先开始学习最基础的数据结构--数组。

        我相信对于数组,大家肯定是不陌生,因为数组在大多数的语言中都有,也是大家在编程中常常会接触到的。我不会说数组有多困难,但是它绝对不是像我们所想的那么简单而已。

        带着问题进入今天的课题:为什么数组的下表从0开始,而不是从1开始

什么是数组

        我们还是从专业的角度来介绍一下数组:数组是一种线性表数据结构。它用一组连续的内存空间,来储存一组相同类型的数据。其中有几个知识点是需要我们了解的。

第一点是线性结构的概念。线性结构具有以下几个特点:

  1. 有唯一的首元素
  2. 有唯一的尾元素
  3. 除了首元素,所有的元素都有唯一的前驱
  4. 除了尾元素,所有的元素都有唯一的后继
  5. 数据元素之间存在“一对一”的关系

只要不满足以上特点的,就是非线性表。

常见的线性结构有:栈,数组,队列,堆,链表

常见的非线性结构有:树,图

        第二点是连续的内存空间和相同类型的数据结构。这两点正是数据数组强大的主要原因--高效的访问操作(随机访问)。我们知道数组在查询操作中具有很高的效率。但是原因是什么呢?我们一起来分析一下。

        例: 我们定义一个int 类型的数组,长度为10。假设首地址是base_address是1000。,那么它在内存中的分布应该如下图:

        比如我现在要访问数组中第5个数据a[4] (数组下标从0开始)。操作系统就会从 base_address+4*sizeof(int) 地址进行取值。正是通过这个公式实现数组的随机访问

        其实在这里,我们就可以回答刚开始导入的问题了:为什么数组的下表从0开始,而不是从1开始?

原因有二:

  1. 我们知道数组的随机访问是通过base_address+i*sizeof(data_type_size)公式计算的。如果数组的下表从1开始,数据在内存中的分布是不会改变的。上面的例子就是:访问数组中第5个数据a5。操作系统就会从base_address+(i-1)*sizeof(data_type_size)这个地址进行取值。相对于上面的公式,多了一个减法操作。(这种常用操作,对于CPU而言,性能的提升可能是很大的)。但这并不是主要原因,因为也有语言中数组的下表不是从0开始。
  2. 历史原因,因为C语言作为最早出现的高级语言,它的数组下标就是从0开始的。后面java等其它高级语言在创建之初,就继承了这一特性。(大部分人都已习惯从0开始)

数组的增删查

        数组的最大优势就是高效的查询。但是这其中也存在一定的坑。比如:数组的查询复杂度是O(1)。这句话是正确的吗?

错误的,因为即使是有序的数组,采用二分法。查询的复杂度也应该是O(logn)。准确的说法应该是:数组根据下标查询的复杂度是O(1)

数组的增加和删除是比较低效的操作了。因为增加一个或者是删除一个你要保证内存数据的连续性。

数组的越界

        数组的越界总是会发生一些意想不到的问题。我们看分析一下该代码,看看是什么现象。

int main(int argc, char* argv[]){
    int i = 0;
    int arr[3] = {0};
    for(; i<=3; i++){
        arr[i] = 0;
        printf("hello world\n");
    }
    return 0;
}

        现象是无限的打印“hello world”。我相信代码的错误点,大家肯定是知道的————数组越界访问。但是为什么会造成无限打印呢?这需要了解linux 虚拟内存分布以及栈的概念了。

        我们首先要知道linux进程的虚拟内存为4G,并且不同的地址分配着不同的资源。可参考下图:

其中各个空间分布,我就不再赘述了。只介绍该题需要分析的栈。需要注意以下几点:

  1. 栈也是一个数据结构,它的特点是先进后出。
  2. 并且它是向下连续增长的
  3. 一个线程中,是共享一个栈的。(线程中的栈大小是有限制)

我们知道局部变量是分布在栈中的,根据上面的代码,我们可以开始分析。

  1. int i=0;//i变量入栈,假设地址为1000
  2. int arr[3]={0};//arr数组入栈,arr[0]地址为988,arr[1]地址为992,arr[2]地址为996。

        分析到这里,我们就知道了,当访问arr[3]时,计算机根据base_address+3*data_type_size公式,实际上访问的是i变量,将i设置为了0,导致重新循环开始。所以一直无限打印“hello world”。

总结

        该篇简单介绍了数组这个数据结构。分析了它为什么能够实现随机访问。以及数组越界可能会带来的一些问题。数组比较适合用来查询,但是删除和增加,就比较低效了。

        对于超级大的数组,每次删除都会搬移其它数据。如果删除操作比较频繁。那么就是比较低效的。为了减少搬移数据的次数,我们可以将删除的变量进行标记(已使用或未使用),当内存不足时,再进行释放。这样就减少了搬移次数,提高效率。其实这也是JVM标记清除垃圾算法的思想。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免费分享自建GPT网站,畅享无限创意!

PS&#xff1a;该文章基本为GPT3.5 撰写 这里与大家分享一个令人兴奋的消息&#xff1a;我建立了一个全新的GPT网站&#xff0c;并且我将免费提供给大家使用&#xff01;这个网站基于最新的GPT-3.5 Turbo模型&#xff0c;能够为您带来无限的创意和惊喜。 在这个免费的GPT网站…

一条命令彻底卸载Linux自带多个版本jdk

一条命令彻底卸载Linux自带多个版本jdk 检查系统已经安装的jdk rpm -qa | grep java卸载所有已经安装的 jdk xargs 将参数逐个传递 将已安装的 java 程序逐个当做参数传递给 rpm -e --nodeps rpm -qa | grep java | xargs rpm -e --nodeps再次检查系统已经安装的jdk rpm -qa | …

python-opencv划痕检测

python-opencv划痕检测 这次实验&#xff0c;我们将对如下图片进行划痕检测&#xff0c;其实这个比较有难度&#xff0c;因为清晰度太差了。 我们做法如下&#xff1a; &#xff08;1&#xff09;读取图像为灰度图像&#xff0c;进行自适应直方图均衡化处理&#xff0c;增强图…

基于爬行动物算法优化概率神经网络PNN的分类预测 - 附代码

基于爬行动物算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于爬行动物算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于爬行动物优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

梦开始的地方——Adobe Premiere Pro

今天&#xff0c;我们来说说一款老生常谈的相信也是很多人都经常迫切需要的软件。Adobe Premiere Pro&#xff0c;简称Pr&#xff0c;是由Adobe公司开发的一款视频编辑软件。 Premiere Pro是视频编辑爱好者和专业人士必不可少的视频编辑工具。它可以提升您的创作能力和创作自由…

Leetcode—6.N字形变换【中等】

2023每日刷题&#xff08;三十七&#xff09; Leetcode—6.N字形变换 算法思想 参考k神的题解 实现代码 class Solution { public:string convert(string s, int numRows) {if(numRows < 2) {return s;}vector<string> rows(numRows);int flag -1;int i 0;for(…

使用docker命令_进入容器_登录mysql服务_并执行sql语句---Docker工作笔记005

今天就用到了,不得不说用docker用到的还是少,记录一下,常用的也就这些吧. 首先执行: docker ps [root@localhost dataease-1.18.9]# docker ps CONTAINER ID IMAGE COMMAND CREATED …

【NLP】培训LLM的不同方式

在大型语言模型&#xff08;LLM&#xff09;领域&#xff0c;存在多种具有不同手段、要求和目标的培训机制。由于它们有不同的用途&#xff0c;因此重要的是不要将它们相互混淆并了解它们适用的不同场景。 在本文中&#xff0c;我想概述一些最重要的训练机制&#xff0c;包括预…

气候变化和人类活动对中国植被固碳的贡献量化数据月度合成产品

简介&#xff1a; 气候变化和人类活动对中国植被固碳的贡献量化数据月度合成产品包括中国2001~2018年地表短波波段反照率、植被光合有效辐射吸收比、叶面积指数、森林覆盖度和非森林植被覆盖度、地表温度、地表净辐射、地表蒸散发、地上部分自养呼吸、地下部分自养呼吸、总初级…

挺扎心!好不容易有了一个offer,就因为背调出之前有仲裁记录,offer黄了,这已经是第二次了!...

仲裁记录会影响之后求职吗&#xff1f; 最近有一位程序员向我们讲述了他的遭遇&#xff1a; 大环境不好&#xff0c;好不容易有了一个offer&#xff0c;却因为背调出跟之前公司有仲裁经历&#xff0c;offer黄了&#xff0c;这已经是第二次因为这个原因黄offer了。 他说自己快抑…

redis运维(十三) hash哈希

一 哈希 ① 定义 hash&#xff1a; 散列说明&#xff1a;key对应是值是键值对[python中的字典],其中键在redis中叫field.形如&#xff1a;value[{field1,value1},...{fieldN,valueN}],值本身又是一种键值对结构 ② 优点和缺点 wzj_height 180wzj_age 18等价 -->…

Go语言多线程爬虫万能模板它来了!

对于长期从事爬虫行业的技术员来说&#xff0c;通过技术手段实现抓取海量数据并且做到可视化处理&#xff0c;我在想如果能写一个万能的爬虫模板&#xff0c;后期遇到类似的工作只要套用模板就能解决大部分的问题&#xff0c;如此提高工作效率何乐而不为&#xff1f; 以下是一个…

逸学java【初级菜鸟篇】9.5枚举

hi&#xff0c;我是逸尘&#xff0c;一起学java吧 枚举是信息的标志和分类 当一个变量有几种固定可能的取值时&#xff0c;就可以将它定义为类型的枚举。 优点&#xff1a;代码可读性好&#xff0c;入参约束严谨&#xff0c;代码优雅&#xff0c;是最好的信息分类技术&#x…

IDEA集成Git

一、配置Git忽略文件 例如&#xff1a;用eclipse创建的项目有其特定的文件&#xff0c;例如&#xff1a;.classpath,.project文件&#xff0c;而用IDEA创建的项目也有其特定的文件&#xff1a;.xml,.iml,.target,我们需要最好忽略他们。 为什么要忽略他们&#xff1f; 与项目…

装饰器设计模式是什么?什么是 Decorator 装饰器设计模式?Python 装饰器设计模式示例代码

什么是 Decorator 装饰器设计模式&#xff1f; 装饰器模式是一种结构型设计模式&#xff0c;它允许向现有对象动态地添加新功能&#xff0c;同时不改变其结构。这种模式实现了对对象的包装&#xff0c;称为装饰器&#xff0c;并且可以在运行时动态地添加、修改或删除对象的行为…

httpd(Web服务器)

名词解释 1、URL&#xff1a;Uniform Resource Locator&#xff0c;统⼀资源定位符 2、⽹址格式&#xff1a;<协议>://<主机或主机名>[:port]/<⽬录资源,路径> 3、主机地址/主机名&#xff1a;主机地址是服务器在因特⽹所在的IP地址。主机名就需要域名解析…

用于计算机屏幕安全摄像头系统:Screen Anytime Crack

Screen Anytime 是一款软件&#xff0c;旨在自动将整个用户会话或 PC/服务器/VM/Kiosk 的 /RDP/Citrix/RemoteApp 会话的屏幕活动记录到视频日志文件中&#xff0c;以用于记录、审核和监控目的。通过重播其高度压缩的视频&#xff0c;您可以轻松回顾单台计算机或一组服务器/PC …

Power Apps-下拉列表控件

插入一个下拉列表控件 设置值的两种方式 1.通过属性items写数组设置 2.通过连接数据表&#xff0c;先在右侧操作面板中选择项目中的数据表 再从Value中选择其中一列&#xff0c;下拉就可以选择该列全部行的值 但是这样会导致有很多重复的字段&#xff0c;所以可以在items属性里…

最近技术圈发生了很多大事,来聊聊

如标题所说&#xff0c;最近这几年全球都大事频发。有事甚至不知道是我更关心社会和时政、还是真的进入一个大变革时代。 可以确认的是&#xff0c;现在这个时代、科技的发展到了一个可感知到越来越快的速度。 … 前几天&#xff0c;当下AI 领域最有知名的人奥特曼被 OpenAI…

Leaflet实现轨迹播放动画效果

效果图如下&#xff1a; <!DOCTYPE html> <html><head><title>轨迹</title><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><!-- 引入样式 -->…