Objetivo
En esta unidad, se busca que el estudiante pueda entender y comparar las distintas representaciones
internas de arreglos, determinando para cada una:
facilidad de manejo
rapidez de acceso
Definicin
Un arreglo es un sistema de elementos del mismo tipo, indizado por un sistema de coordenadas
enteras, que permite acceder y alterar elementos individuales .
Ejemplos del uso de arreglos:
int arreglo [5] ; // indizado 0..4
int matriz [5][10] ; // indizado 0..4 * 0..9
arregloPascal: array [11..20, 1..5] of integer ; // de tamao 10 * 5
Acceso de los elementos:
arreglo[3] = 4 ,
matriz [4,9] = 5 ;
arregloPascal [12, 3] = 100 ;
Problema
En los ejemplos anteriores, vemos que la notacin para acceder los elementos es relativamente simple.
Sin embargo, para el compilador no es tan simple, ya que implica una serie de clculos relativamente
complejos.
La razn principal, se debe a que cuando se declara un arreglo, la variable que representa dicho arreglo
es en realidad una apuntador al primer elemento del arreglo, como es el caso de las variables arreglo,
matriz y arregloPascal en los ejemplos anteriores.
Notacin
parejas lmite
direccin inicial
a = &A[n1,n2,...,nk]
Almacenamiento lexicogrfico
Acceder un elemento implica el clculo de una direccin, lo que significa que debe haber un orden en
la memoria entre los elementos del arreglo. Dicho orden es el orden lexicogrfico
orden lexicogrfico por fila: la posicin (a1, a2 , , ak) es menor que (b1, b2, , bk), si y slo si
para algn 1 < j <= k, existe un i tal que ai = bi, para 1 <= i < j, y aj < bj
Por ejemplo: si tenemos las coordenadas A=(1, 5, 1, 9) y B = (1, 5, 2, 8), el orden lexicogrfico nos
dice que A< B. En este caso k = 4, entonces necesitamos un nmero entre 1 y 4 (la variable j), que sea
el ndice de la coordenada tal que las coordenadas anteriores sean iguales en A y B, y aj sea menor a bj.
En este caso, ese nmero j corresponde a 3. Ntese que en la primera y segunda coordenada tienen el
mismo valor, y en la tercera se cumple que 1 < 2.
aplicaciones
Compiladores: stos deben representar en memoria las instrucciones de alto nivel
Existen algunos lenguajes de cuarta generacin que no tienen manejo de arreglos, lo que obliga
a hacer nuestra propia representacin de los arreglos
Programacin de algunas calculadoras cuyo BASIC no tiene manejo de arreglos o matrices
Caso unidimensional
Supongamos el siguiente vector V de 4 elementos
1 2 3 4
cul sera la frmula que nos permita mapear cualquier elemento de este vector? Loc(V[i]) = ?
Por ejemplo: encontrar el elemento V[3].
a = &V[1]
Loc (V[3]) = a + 2
Suponiendo que el par lmite de la dimension es 1..4, Loc (V[i]) = a + i - 1
Si el par lmite fuera 10..13
10 11 12 13
Loc(V[12]) = ? = a + 12 - 10
Con dimensiones generales n1..m1 entonces
Loc (V[i]) = a + i - n1
Caso bidimensional
Supongamos la matriz de 3*4 con los pares lmites 1..3 * 1..4
a = &A[1,1]
1,1 1,2 1,3 1,4
2,1 2,2 2,3 2,4
3,1 3,2 3,3 3,4
En memoria, realmente queda as:
1,1 1,2 1,3 1,4 2,1 2,2 2,3 2,4 3,1 3,2 3,3 3,4
cul sera la frmula que nos permita mapear cualquier elemento de esta matriz?
Por ejemplo: encontrar el elemento A[2,3]. Dado que el elemento est en la fila 2, sabemos que se debe
avanzar totalmente la primera fila. De esta forma tenemos que avanzar 4 elementos, ya que cada fila es
de tamao 4.
Loc (A[2,3]) = ( a + 4) + ( 3 - 1)
con dimensiones 1..3*1..4, Loc (A[i,j]) = a + (i-1)*4 + j - 1
En general, con dimensiones n1..m1*n2..m2, Loc (A[i1,i2]) = a + (i1-n1) * (m2-n2+1) + (i2-n2)
Si se tiene 11..20 * 100 .. 110 entonces el tamao de las filas ser m2-n2+1 = 110 - 100 + 1
int X [111] : // se mapean de 0 .. 110
Caso tridimensional
1..3 * 1..4 * 1..2
Tenemos que tamao de la primera dimensin = tamao una matriz = T1
Tenemos que tamao de la segunda dimensin = tamao una fila = T2
Loc (A[2,3,2]) = a + 1*T1 + 2*T2 + 1 = a + 1*(4*2) + 2*(2) + 1
Si tenemos los pares lmites 1..m1 * 1..m2 * 1..m3
Loc (A[2,3,2]) = a + 1*T1 + 2*T2 + 1
= a + 1*(m3)*(m2) + 2*(m3) + 1
en general, para n1..m1 * n2..m2 * n3..m3
Loc (A[i,j,k]) = a + (i-n1)*T1+ (j-n2)*T2 + (k-n3)
= a + (i-n1)*(m3-n3+1)*(m2-n2+1) + (j-n2)*(m3-n3+1) + (k-n3)
Caso k-dimensional
n1..m1 * n2..m2 * ... * nk..mk
Loc (A[i1, i2, ... ,ik) = a + (i1-n1)*|1a. Dim| + (i2-n2)*|2a.Dim| + ... + (ik-1 - nk-1)*|k-1 dim| + (ik-nk)
Tamao de las dimensiones:
el ltimo vector ( dimensin k-1) = mk - nk + 1
la ltima matriz ( dimension k -2 ) = (Mk-1 - Nk-1 + 1) * (mk - nk + 1)
el ltimo cubo (dimensin k-3) = (Mk-2 - Nk-2 + 1) * (Mk-1 - Nk-1 + 1) * (mk - nk + 1)
...
dimensin K-j = (Mk-j-1 - Nk-j-1 -1) * ...* (Mk-1 - Nk-1 + 1) * (mk - nk + 1)
..
la primera dimensin ( K-j cuando j=k)
(M1 - N1 -1) * ...* (Mk-1 - Nk-1 + 1) * (mk - nk + 1)
= a + (i1-n1)*|1a. Dim| + (i2-n2)*|2a.Dim| + ...(ik-1-nk)*|k-1 dim| + (ik-1)
Loc (A[i1,i2,..,ik]) = SUM desde I = 1 hasta k ( (Ii - Ni) * MULT desde x=I hasta k-1 ( Mx - Nx - 1) ) =
= (i1 - n1 )* (m2-n2+1)(m3-n3+1)....(mk-nk+1) +
(i2 - n2 ) * (m3-n3+1)....(mk-nk+1) +
.... +
(ik-1 - nk-1) * (mk-nk+1) +
(ik - nk)
EJERCICIO 1:
orden lexicogrfico por columna: la posicin (a1, a2 , , ak) es menor que (b1, b2, , bk), si y
slo si para algn 1 < j <= k, existe un i tal que ai = bi, para todo j < i <= k, y aj < bj
Ej. Matriz 1..3 * 1..4
1,1 2,1 3,1 1,2 2,2 3,2 1,3 2,3 3,3 1,4 2,4 3,4
sea A un arreglo de n1..m1 * n2..m2 ordenado lexicogrficamente por columnas
Deducir LOC(A[i,j])
= a + (j-n2) * (m1-n1+1) + (i-n1)
En general:
Para el arreglo A: n1..m1 * n2..m2 * .... * nk..mk
LOC ( A[i1, i2, .., ik] = a + (ik - nk)* (m1 - n1 +1) * (m2 - n2 + 1) * ...* (mk-1 - nk-1 +1 ) +
(ik-1 - nk-1 ) * (m1 - n1 +1) * (m2 - n2 + 1) * ...* (mk-2 - nk-2 +1 ) +
...
(i2 - n2 ) * (m1 - n1 +1) +
(i1 - n1 )
Algoritmo
public class ArregloLexicografico<E> extends ArregloGeneral<E> {
.
.
.
public E get (int i[]) {
int sumatoria = 0 ;
for (x = 0; x < k ; x++) {
int productoria = 1 ;
for (y=x; y < k ; y++) {
productoria *= (m[y] - n [y] + 1) ;
}
sumatoria += (i[x]-n[x]) * productoria ;
}
return objs [sumatoria] ;
}
.
.
}
Calcular O ( get(), N) = ? = k2
Arreglos esparcidos
Vimos que el uso de arreglos lexicogrficos tiene el mejor rendimiento posible (constante) para el
acceso de elementos por ndice. Sin embargo, el hecho de que necesiten reservar memoria contigua
para todos sus posibles elementos, implica que existen situaciones en las que no son recomendables,
debido principalmente a dos factores:
1. Desperdicio de memoria: consideremos una matriz de 1,000 por 1,000 elementos, de los cuales
slo se estn utilizado 10. Sera un gran desperdicio de memoria, alojar 1,000,000 de elementos
para slo utilizar 10.
2. Incapacidad de alojar espacio para todos los posibles elementos: las hojas electrnicas tienen
una gran capacidad de celdas, pero normalmente slo se utiliza una pequea porcin de
ellas: Excel tiene su mxima celda en IV65536, lo que significa una capacidad para
(26*8+22)*65536 = 15,073,280 celdas. Si cada una de estas ocupara 1 byte, no tendramos
memoria suficiente para una hoja electrnica..
En cualquiera de estos casos resultan tiles los arreglos esparcidos, los cuales tienen como
caracterstica fundamental que slo utilizan la memoria realmente necesaria conforme se agregan
elementos al arreglo.
Tcnicas de representacin
Entre muchas tcnicas para lograr los arreglos esparcidos, distinguiremos dos principales:
Arreglos lexicogrficos de encabezados, con celdas de referencias cruzadas.
Listas de encablezados
El uso de arreglos lexicogrficos para los encabezados se ilustran en la siguiente figura:
Se tiene un control de encabezados, el cual contiene dos apuntadores: uno para el arreglo de las filas y
el otro para las columnas. Los encabezados no necesitan ms informacin que el apuntador al primer
nodo de la fila o columna. Cada uno de los nodos tiene la siguiente estructura::
Los cuatro apuntadores de navegacin nos sirven para facilitar los recorridos y bsqueda de cada nodo.
Notemos que, adems de la info, se debe tener en cada nodo la informacin de los ndices que
representan, ya que la caraterstica de esparcido no permite calcular el ndice de un nodo basado en sus
posicin de forma fcil. Se podra omitir esta informacin, para para buscar cada nodo implicara una
doble bsqueda, por fila y columna, para cada nodo, lo cual lo hara muy ineficiente.
La estrategia bsica del algoritmo de localizacin de un elemento A[i,j]
Seleccionar el encabezado de las filas, aunque tambin puede ser por columna
Para cada nodo en la lista de la fila i
Si nodo.j < j
nodo = nodo.der ; //seguimos buscando
sino
si nodo.j=j
return nodo ; //encontramos el nodo
sino
return null ; //no se encuentra el nodo con los ndices indicados
fin
fin
Una implementacin ms formal, podra ser la siguiente:
public class ArregloEsparcido<E> extends ArregloGeneral<E> {
.
.
.
public E get (int i[]) {
/* resumiendo a bsqueda por filas */
Nodo n = fila [i] ;
while (n != null && n.col < j) {
n = n.derecha ;
}
if ( n == null )
return null ;
else
return n.obj ;
}
.
.
}
Las otra tcnica de representacin est basada en que tambin los encabezados son listas, en vez de
arreglos lexicogrficos. As, otra representacin de la matriz anterior es as:
stos nodos pueden ser utilizados en cualquier dimensin. Slo es necesario que contengan el ndice
que representan.
Esta representacin al seguir manteniendo los nodos con doble enlace en ambas dimensiones, permite
tener la misma flexibilidad en el recorrido de elementos que la representacin con encabezados de
arreglos. La diferencia bsica es que el recorrido en los encabezados. Sin embargo, cuando se tienen
mltiples dimensiones, mantener en los nodos el doble enlace hacia cualquier direccin, complica de
gran manera las operaciones de insercin y eliminacin, adems de representar un consumo alto de
memoria por uso de dos apuntadores por nodo, por dimensin. Para estos casos se podra utilizar una
representacin como la siguiente:
Comparacin de tcnicas
El rendimiento del acceso a los arreglos, est dado por la representacin interna
Criterios de comparacin