¿Por qué el acceso a un elemento en una matriz lleva un tiempo constante?

7 minutos de lectura

Digamos que tengo una matriz como:

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

cuando accedo a un elemento, como a[3], ¿qué sucede realmente detrás de escena? ¿Por qué muchos libros de algoritmos (como el libro de Cormen…) dicen que lleva un tiempo constante?

(Solo soy un novato en programación de bajo nivel, así que me gustaría aprender más de ustedes)

  • Solo 10 votos a favor. esto merece atencion

    – Farhan Shirgill Ansari

    22 de julio de 2015 a las 12:49


La matriz, efectivamente, se conoce por una ubicación de memoria (un puntero). Accediendo a[3] se puede encontrar en tiempo constante, ya que es solo ubicación_de_a+3*tamaño(int).

En C, puedes ver esto directamente. Recuerda, a[3] es lo mismo que *(a+3) – que es un poco más claro en términos de lo que está haciendo (desreferenciando el puntero “3 elementos”).

  • Y porqué *(a+3) es lo mismo que *(3+a)podemos escribir a[3] tambien como 3[a], un hecho invariablemente útil en IOCCC y similares. 🙂

    – ShreevatsaR

    4 de septiembre de 2011 a las 7:36

  • @ShreevatsaR: Sí, pero… escribir 3[a] no tiene muchos usos prácticos, pero usar *(a+3) suele ser útil en escenarios del mundo real…

    – Reed Copsey

    4 de septiembre de 2011 a las 7:40

  • Su explicación incluso se mantendría cuando el índice que se usa también sea una variable. Pero como aquí es una constante (3) el compilador puede incluso realizar todos los cálculos de antemano y, en tiempo de ejecución, el programa puede acceder a la memoria directamente. Entonces, de hecho, no solo es constante, sino realmente pequeño.

    – Jens Gusted

    4 de septiembre de 2011 a las 8:27

una matriz de 10 variables enteras, con índices del 0 al 9, puede almacenarse como 10 palabras en las direcciones de memoria 2000, 2004, 2008, … 2036, de modo que el elemento con índice i tenga la dirección 2000 + 4 × i. este proceso toma una multiplicación y una suma. Dado que estas dos operaciones toman un tiempo constante, podemos decir que el acceso se puede realizar en un tiempo constante.

  • Esto es exactamente lo que quería. Es constante pero que hay de matematicas detras de esto—- lo has explicado muy bien.

    – Nav Deep Singh

    24 de agosto de 2015 a las 18:36

avatar de usuario
xánatos

Solo para ser completo, “¿a qué estructura se accede en tiempo lineal?” A Lista enlazada Se accede a la estructura en tiempo lineal. Para obtener el n elemento por el que tienes que viajar n-1 elementos anteriores. Ya sabes, como una grabadora o un casete VHS, donde ir al final de la cinta/VHS tenías que esperar mucho tiempo 🙂

Una matriz es más similar a un disco duro: cada punto es accesible en tiempo “constante” 🙂

Esta es la razón por la cual la memoria RAM de una computadora se llama RAM: memoria de acceso aleatorio. Puede ir a cualquier ubicación si conoce su dirección sin atravesar toda la memoria antes de esa ubicación.

Algunas personas me dijeron que el acceso a la HD no es realmente en tiempo constante (donde por acceso me refiero a “tiempo para colocar la cabeza y leer un sector de la HD”). Tengo que decir que no estoy seguro de ello. He buscado en Google y no he encontrado a nadie que hable de ello. SÍ sé que el tiempo no es lineal, porque todavía se accede al azar. Al final, si cree que el acceso a HD no es lo suficientemente constante para usted (pero entonces, ¿qué es constante? ¿El acceso a la RAM? ¿Teniendo en cuenta las optimizaciones de Caché, Precarga, Localidad de datos y Compilador?), Siéntase libre de considerar la oración como Una matriz es más similar a una memoria USB: se puede acceder a cada punto en un tiempo “constante” 🙂

  • los discos duros son un mal ejemplo de una memoria de acceso aleatorio, porque eso es exactamente lo que no son. ¿Quizás usar una memoria USB o un disco de estado sólido como ejemplo?

    – balbuceo

    4 de septiembre de 2011 a las 7:41

  • Sí y no… Técnicamente, la parte “externa” de un HD es más rápida que la parte interna, pero esto lo ignoraremos. El acceso a un archivo en el HD se realiza en tiempo constante (o al menos no en tiempo lineal). Si tienes un archivo en un HD o un millón de archivos en un HD, acceder a uno de ellos llevará el mismo tiempo (no exactamente, pero es más un modelo teórico que la realidad física en la que vivimos :-)).

    – xánatos

    4 de septiembre de 2011 a las 7:44

  • ¿Se puede explicar el -1? Lo repensé un poco. El tiempo de acceso a HD está en tiempo constante. Dado un HD, tiene un tiempo de búsqueda medio. Entonces, buscar el comienzo de un archivo llevará ese tiempo.

    – xánatos

    4 de septiembre de 2011 a las 8:05

  • No voté en contra, pero sospecho que se debe a la afirmación de que el acceso a HD es un tiempo constante. Si la cabeza de lectura de un HD está a las 3 en punto del disco, el tiempo que tarda en leer otro sector también está influenciado por la ubicación de dicho sector. Si está a las 9 en punto, tardará considerablemente más que si está junto al sector debajo del cabezal de lectura. Después de todo, esta es la razón por la que se han inventado muchas estrategias de optimización sofisticadas para acelerar el acceso pseudoaleatorio en HD.

    – balbuceo

    4 de septiembre de 2011 a las 8:25


  • “Tiempo constante” solo significa limitado por una constante, es decir O(1). Técnicamente hablando, cualquier medio finito tiene O(1) tiempo de acceso, pero para una cinta la constante es tan mala y la escala de tiempo es tal que es más práctico tratarla como si la cinta fuera potencialmente infinita. Para discos duros (suponiendo que no haya daños y bucles de reintento infinitos), el tiempo de acceso es muy pequeño y, a efectos prácticos, debe considerarse O(1).

    – R.. GitHub DEJA DE AYUDAR A ICE

    4 de septiembre de 2011 a las 13:02

Porque las matrices se almacenan en la memoria secuencialmente. Entonces, en realidad, cuando accedes a la matriz[3] le está diciendo a la computadora: “Obtenga la dirección de memoria del comienzo de la matriz, luego agregue 3 y luego acceda a ese lugar”. Dado que agregar toma un tiempo constante, ¡también lo hace el acceso a la matriz!

“tiempo constante” realmente significa “tiempo que no depende del ‘tamaño del problema'”. Para el ‘problema’ “sacar algo de un contenedor”, el ‘tamaño del problema’ es el tamaño del contenedor.

Acceder a un elemento de matriz lleva básicamente la misma cantidad de tiempo (esto es una simplificación) independientemente del tamaño del contenedor, porque se utiliza un conjunto fijo de pasos para recuperar el elemento: se calcula su ubicación en la memoria (esto también es una simplificación), y luego se recupera el valor en esa ubicación en la memoria.

Una lista enlazada, por ejemplo, no puede hacer esto, porque cada enlace indica la ubicación del siguiente. Para encontrar un elemento tienes que trabajar con todos los anteriores; en promedio, trabajará con la mitad del contenedor, por lo que el tamaño del contenedor obviamente importa.

avatar de usuario
Sunil Kumar Jha

Array es una colección de tipos similares de datos. Entonces, todos los elementos ocuparán la misma cantidad de memoria. Por lo tanto, si conoce la dirección base de la matriz y el tipo de datos que contiene, puede obtener fácilmente la matriz de elementos[i] en tiempo constante utilizando la fórmula que se indica a continuación:

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];

Por lo tanto, es claramente visible que puede obtener un elemento en un tiempo constante si conoce la dirección base y el tipo de datos que contiene. Por favor visita este enlace para saber más sobre la estructura de datos de matriz.

avatar de usuario
nikhiltejadonkana

Una matriz es secuencial, lo que significa que la dirección del siguiente elemento en la matriz está junto a la actual. Entonces, si desea obtener el quinto elemento de una matriz, calcule la dirección del quinto elemento sumando la dirección base de la matriz con 5. Esta dirección directa ahora se usa directamente para obtener el elemento en esa dirección.

Ahora puede hacer la misma pregunta aquí: “¿Cómo sabe/accede la computadora a la dirección calculada directamente?” Esta es la naturaleza y el principio de la memoria de computadora (RAM). Si está más interesado en cómo la RAM accede a cualquier dirección en tiempo constante, puede encontrarlo en cualquier texto de organización de computadora o simplemente puede buscarlo en Google.

¿Ha sido útil esta solución?