为什么访问数组中的元素需要恒定的时间?

时间:2011-09-04 07:31:51

标签: c arrays time constants complexity-theory

假设我有一个数组:

int a [] = {4,5,7,10,2,3,6}

当我访问一个元素,例如[3]时,它在场景后面实际发生了什么? 为什么许多算法书籍(如Cormen书籍......)说它需要一个恒定的时间?

(我只是一个低级编程的菜鸟,所以我想向你们学习更多)

8 个答案:

答案 0 :(得分:22)

有效地,数组由内存位置(指针)知道。访问a[3]可以在固定时间内找到,因为它只是location_of_a + 3 * sizeof(int)。

在C中,您可以直接看到这一点。请记住,a[3]*(a+3)相同 - 就其正在做的事情而言更清楚一些(取消引用指针“3项”)。

答案 1 :(得分:15)

具有索引0到9的10个整数变量的数组可以在存储器地址2000,2004,2008,... 2036处存储为10个字,使得具有索引​​i的元素具有地址2000 + 4×i。   这个过程需要一个乘法和一个加法。因为这两个操作需要一个恒定的时间。所以我们可以说访问可以在恒定的时间内执行

答案 2 :(得分:14)

要完成,“在线性时间访问什么结构?”以线性时间访问Linked List结构。要获取n元素,您必须浏览n-1之前的元素。你知道,就像磁带录音机或VHS录音带一样,你需要等待很长时间才能到达磁带/ VHS的末端: - )

数组更类似于硬盘:每个点都可以在“常量”时间访问:-)

这就是计算机的RAM称为RAM:随机存取存储器的原因。如果您知道其地址而不遍历该位置之前的所有内存,则可以前往任何位置。

有些人告诉我,HD访问并非真正处于不变的时间(访问时我指的是“定位头部并读取HD的一个扇区的时间”)。我不得不说我不确定。我用谷歌搜索过,我还没有发现任何人在谈论它。我知道时间不是线性的,因为它仍然是随机访问的。最后,如果您认为高清访问对您来说不够稳定(但那么,什么是常量?RAM的访问?考虑缓存,预取,数据位置和编译器优化?),请随意考虑句子as 数组更类似于USB磁盘棒:每个点都可以在“常量”时间访问: - )

答案 3 :(得分:7)

“恒定时间”实际上意味着“不依赖于'问题规模'的时间”。对于'问题'“从容器中取出一些东西”,“问题大小”就是容器的大小。

访问数组元素花费的时间基本相同(这是一个简化),无论容器大小如何,因为使用一组固定的步骤来检索元素:它在内存中的位置(这也是一种简化)计算,然后检索内存中该位置的值。

例如,链接列表无法执行此操作,因为每个链接都指示下一个链接的位置。要找到一个元素,你必须完成以前的所有元素;平均而言,你将通过容器的一半工作,因此容器的大小显然很重要。

答案 4 :(得分:5)

因为数组按顺序存储在内存中。实际上,当您访问数组[3]时,您正在告诉计算机,“获取数组开头的内存地址,然后向其中添加3,然后访问该位置。”由于添加需要恒定的时间,因此阵列访问也是如此!

答案 5 :(得分:2)

Array是类似数据类型的集合。因此,所有元素都将占用相同数量的内存。因此,如果您知道数组的基址和它所拥有的数据类型,您可以使用下面的公式轻松地在恒定时间内获取元素Array [i]:

int takes 4 bytes in a 32 bit system.
int array[10];
base address=4000;
location of 7th element:4000+7*4.
array[7]=array[4000+7*4];

因此,如果您知道它所拥有的基本地址和数据类型,它可以清晰地看到您可以在恒定时间内获得第i个元素。 请访问this链接以了解有关阵列数据结构的更多信息。

答案 6 :(得分:1)

数组是顺序的,这意味着数组中的下一个元素地址紧邻当前数据。因此,如果你想获得数组的第5个元素,你可以通过将数组的基址与5相加来计算第5个元素的地址。这个直接地址现在直接用于获取该地址的元素。

您现在可以在此处进一步提出相同的问题 - “计算机如何直接知道/访问计算出的地址?”这是计算机存储器(RAM)的本质和原理。如果您对RAM如何在固定时间内访问任何地址感兴趣,您可以在任何计算机组织文本中找到它,或者您可以直接进行谷歌搜索。

答案 7 :(得分:1)

如果我们知道需要访问的内存位置,那么此访问是恒定的。在数组的情况下,通过使用基指针,元素索引和元素大小来计算存储器位置。这涉及乘法和加法运算,这需要花费恒定的时间来执行。因此,数组内部的元素访问需要恒定的时间。