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

一: 文章开头问一下各位几个问题 

问题1: 数组到底哪里快?查找快吗?

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

问题2: 为什么数组能支持随机访问呢?换而言之,为什么数组能直接通过角标访问元素呢?

答案: 

  1. 数组占用的内存空间是连续的
  2. 数组中都为同一类型的元素

二: 举例分析

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

在这里插入图片描述

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

                                                        1000+2∗4 

其中1000是我们的基地址,2代表了我们的偏移量,4代表了每个元素所占内存的大小(int占4个字节)这样通过一次计算,我们就能直接找到数组中对应角标的位置了。

讲到这里,我们不妨再思考一个问题: 

问题3: **数组为什么角标都是从0开始呢**

大家想一想,如果我们的角标是从1开始的话,我们上面的公式是不是也得发生变化,就变成了下面这个样子:
                                                     1000+(3−1)∗4

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

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

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

原文地址: 数据结构|数组为什么这么快?_做一个认真的程序员-CSDN博客

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构中,要检索或查找一个数组中的数,可以使用线性查找或二分查找两种方法。 1. 线性查找:从数组的第一个元素开始逐个比较,直到找到目标元素或者遍历整个数组。时间复杂度为O(n),其中n为数组的长度。 下面是一个用C语言实现线性查找的例子: ```c #include <stdio.h> int linear_search(int arr[], int n, int target) { for (int i = 0; i < n; i++) { if (arr[i] == target) { return i; } } return -1; } int main() { int arr[] = {1, 3, 5, 7, 9, 11}; int n = sizeof(arr) / sizeof(arr[0]); int target = 7; int index = linear_search(arr, n, target); if (index == -1) { printf("The target element is not found in the array.\n"); } else { printf("The target element is found at index %d.\n", index); } return 0; } ``` 2. 二分查找:对于已排序的数组,可以使用二分查找算法来速查找目标元素。时间复杂度为O(log n),其中n为数组的长度。 下面是一个用C语言实现二分查找的例子: ```c #include <stdio.h> int binary_search(int arr[], int n, int target) { int left = 0, right = n - 1; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; } int main() { int arr[] = {1, 3, 5, 7, 9, 11}; int n = sizeof(arr) / sizeof(arr[0]); int target = 7; int index = binary_search(arr, n, target); if (index == -1) { printf("The target element is not found in the array.\n"); } else { printf("The target element is found at index %d.\n", index); } return 0; } ``` 这里我们使用了一个while循环来实现二分查找,每次将查找范围缩小一半。当查找到目标元素时,返回其下标;否则,继续缩小查找范围。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值