数据结构|数组为什么这么快?

简介: 数据结构|数组为什么这么快?

我们要分析的第一个问题是:


数组到底哪里快?查找快吗?


可能有的同学第一反应利用数组进行查找的话,时间复杂度为O(1)呀。但是你仔细想想,这样说对吗?即使我们对一个已经排好序的数组通过二分查找法进行查找,时间复杂度也为O(logn)。我们更准确的说法是,数组通过角标进行随机访问的时间复杂度为O(1)。那么接下来进入我们要探讨的第二个问题,为什么数组能支持随机访问呢?换而言之,为什么数组能直接通过角标访问元素呢?


为什么数组能支持随机访问呢?


答案:


1.数组占用的内存空间是连续的

2.数组中都为同一类型的元素


举例分析:


我们可以拿一个长度为5的int数组为例,当我们执行了一段int[] arr = new int[5]后,计算机会给这个数组分配如下图所示的一段内存空间:

image.png

当我们访问角标为2的位置上的元素时我们可以直接通过计算得出该元素对于的内存位置:

image.png


其中1000是我们的基地址,2代表了我们的偏移量,4代表了每个元素所占内存的大小(int占4个字节)这样通过一次计算,我们就能直接找到数组中对应角标的位置了。讲到这里,我们不妨再思考一个问题,**数组为什么角标都是从0开始呢?**大家想一想,如果我们的角标是从1开始的话,我们上面的公式是不是也得发生变化,就变成了下面这个样子:

image.png

这样的话,相对我们之前的公式,是不是平白的多了一次减法的运算?所以,我们角标采用的是相对于基地址的偏移量作为计数标准,这样可以加快我们访问的速度!


通过上面我们知道了,连续的内存空间跟相同的元素这两大利器决定了数组随机访问的特性。另外还需要补充的是,因为数组在内存空间中是连续的,所以CPU在读取时,可以对数组进行“预读”。什么是预读呢?CPU在从内存中加载数据时,会先把读取到的数组加载到CPU的缓存中。而CPU每次从内存中读取数据,并不是只读取那个特定的要访问的地址,而是读取一个数据块,并保存到CPU缓存中,然后下次访问内存数据的时候就会先从CPU缓存开始查找,如果找到就不需要再从内存中取,这样就实现了比直接访问内存更高效的访问机制(这样做的原因是因为,CPU处理数据的速度高于从内存中读取数据的速度)。


关于数组的内容就介绍到这里啦!

我的数据结构与算法专栏:https://blog.csdn.net/qq_41907991/column/info/42035

相关文章
|
18天前
|
存储 Java 程序员
数据结构之 - 深入了解数组数据结构
数据结构之 - 深入了解数组数据结构
34 6
|
18天前
|
存储 算法 搜索推荐
探索常见数据结构:数组、链表、栈、队列、树和图
探索常见数据结构:数组、链表、栈、队列、树和图
84 64
|
11天前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
16 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
11天前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
15 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
1月前
|
存储 Java
java数据结构,线性表顺序存储(数组)的实现
文章介绍了Java中线性表顺序存储(数组)的实现。线性表是数据结构的一种,它使用数组来实现。文章详细描述了线性表的基本操作,如增加、查找、删除、修改元素,以及其他操作如遍历、清空、求长度等。同时,提供了完整的Java代码实现,包括MyList接口和MyLinearList实现类。通过main函数的测试代码,展示了如何使用这些方法操作线性表。
|
3月前
|
存储
【数据结构OJ题】轮转数组
力扣题目——轮转数组
39 2
【数据结构OJ题】轮转数组
|
2月前
|
存储 Java 程序员
"揭秘HashMap底层实现:从数组到链表,再到红黑树,掌握高效数据结构的秘密武器!"
【8月更文挑战第21天】HashMap是Java中重要的数据结构,采用数组+链表/红黑树实现,确保高效查询与更新。构造方法初始化数组,默认容量16,负载因子0.75触发扩容。`put`操作通过计算`hashCode`定位元素,利用链表或红黑树处理冲突。`get`和`remove`操作类似地定位并返回或移除元素。JDK 1.8优化了链表转红黑树机制,提升性能。理解这些原理能帮助我们更高效地应用HashMap。
40 0
|
4月前
|
存储 算法 调度
【数据结构与算法】详解循环队列:基于数组实现高效存储与访问
【数据结构与算法】详解循环队列:基于数组实现高效存储与访问
|
4月前
|
存储 JavaScript 前端开发
JavaScript中的数组是核心数据结构,用于存储和操作序列数据
【6月更文挑战第22天】JavaScript中的数组是核心数据结构,用于存储和操作序列数据。创建数组可以使用字面量`[]`或`new Array()`。访问元素通过索引,如`myArray[0]`,修改同样如此。常见方法包括:`push()`添加元素至末尾,`pop()`移除末尾元素,`shift()`移除首元素,`unshift()`添加到开头,`join()`连接为字符串,`slice()`提取子数组,`splice()`进行删除、替换,`indexOf()`查找元素位置,`sort()`排序数组。还有其他如`reverse()`、`concat()`等方法。
128 2
|
4月前
|
算法 索引 Python
数据结构 数组部分小结
数据结构 数组部分小结