【追求卓越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标记清除垃圾算法的思想。

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

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

相关文章

steam游戏找不到steam_api64.dll,分享三个有效的解决方法

在现代科技发展的时代&#xff0c;游戏已经成为了许多人生活中不可或缺的一部分。而Steam作为全球最大的数字发行平台之一&#xff0c;拥有着庞大的游戏库和活跃的用户群体。然而&#xff0c;在使用Steam时&#xff0c;有些用户可能会遇到Steam_api64.dll丢失的问题&#xff0c…

使用Echarts.js绘制多条折线图

一、页面效果 默认tab为不限&#xff0c;渲染多条折线&#xff1a; 切换tab&#xff0c;只渲染对应tab的一条折线&#xff1a; 二、功能描述 ​ 1、tab选中不限时&#xff0c;图表中同时渲染多条折线&#xff0c;对应多种类型的数据。 ​ 2、切换tab时&#xff0c;如果选中指…

日期格式转化成星期几部署到linux显示英文

异常收集 原因&#xff1a;解决办法仰天大笑出门去&#xff0c;我辈岂是蓬蒿人 传入一个时间获取这个时间对应的是星期几&#xff0c;在开发环境&#xff08;window系统&#xff09;中显示为星期几&#xff0c;部署到服务器&#xff08;linux系统&#xff09;中会显示英文的时间…

VR全景航拍要注意什么,航拍图片如何处理

引言: VR全景航拍技术是当前摄影和航拍领域的新潮流。它采用虚拟现实技术&#xff0c;通过360度全景镜头捕捉画面&#xff0c;可以为观众提供身临其境的视觉体验。在宣传展示中&#xff0c;利用VR全景航拍技术可以为品牌宣传带来更加生动、震撼的视觉效果。 一、航拍注意事项 …

OOM问题排查+Jvm优化

OOM问题排查&#xff1a; 1、top命令&#xff1a;查看cpu和内存的使用情况。 2、jstat命令&#xff1a;查看YGC和FGC情况&#xff0c;一般都是老年代不够用。导致OOM 3、jmap命令&#xff1a; 查看哪个类的实例过多,以每个类占用多少了内存。4、jstack 查看线程与线程之间的阻…

iEnglish全国ETP大赛:教育游戏助力英语习得

“seesaw,abacus,sword,feather,frog,lion,mouse……”11月18日,经过3局的激烈较量,“以过客之名队”的胡玲、黄长翔、林家慷率先晋级“玩转英语,用iEnglish”第三届全国ETP大赛的16强,在过去的周末中,还有TIK徘徊者队、不负昭华队、温柔杀戮者队先后晋级。据悉,根据活动规则,在…

验证码 | 可视化一键管控各场景下的风险数据

目录 查看今日验证数据 查看未来趋势数据 验证码作为人机交互界面经常出现的关键要素&#xff0c;是身份核验、防范风险、数据反爬的重要组成部分&#xff0c;广泛应用网站、App上&#xff0c;在注册、登录、交易、交互等各类场景中发挥着巨大作用&#xff0c;具有真人识别、身…

为Oracle链接服务器使用分布式事务

1 现象 在SQL Server中创建指向Oracle的链接服务器&#xff0c;SQL语句在事务中向链接服务器插入数据。返回链接服务器无法启动分布式事务的报错。 2 解决 在Windows平台下&#xff0c;SQL Server依赖分布式事务协调器&#xff08;MSDTC&#xff09;来使用分布式事务&#xff0…

WPF实战项目十五(客户端):RestSharp的使用

1、在WPF项目中添加Nuget包&#xff0c;搜索RestSharp安装 2、新建Service文件夹&#xff0c;新建基础通用请求类BaseRequest.cs public class BaseRequest{public Method Method { get; set; }public string Route { get; set; }public string ContenType { get; set; } &quo…

Django学习日志09

choices参数的使用 """对于以上可能被我们列举完的字段我们一般都是选择使用choices参来做""" class UserInfo(models.Model):username models.CharField(max_length64)password models.CharField(max_length32)# 先写一个映射关系gender_cho…

Python实现四个组成不相同且无重复的三位数

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 1.题目&#xff1a;有四个数字&#xff1a;1、2、3、4&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;各是多少&#xff1f; for i in range(1,…

Leo赠书活动-10期 【AIGC重塑教育 AI大模型驱动的教育变革与实践】文末送书

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…