Aprendiendo a programar: algoritmos básicos con arrays
Tuesday, February 27th, 2007Definido el concepto de array, en este post se verán algunos algoritmos de las operaciones comunes sobre tablas, tales como inserción de un elemento, búsqueda, ordenación… El objetivo es generar una idea clara de cómo se trabaja con tablas, independientemente del lenguaje, por ello esta vez codificaré en pseudocódigo, teniendo en cuenta que:
- Llamaré N al número de elementos presentes en la tabla.
- Llamaré T al número máximo de elementos en la tabla, el declarado con la tabla. tabla(T) es tabla de…
- El rango irá de 1 a T, siendo tabla[1] el primer elemento y tabla[T] el último. (Si codificas en C, ten en cuenta que el índice de los arrays comienza en cero y no en uno)
Lectura y escritura
Como se vió en la primera parte, se puede hacer a un elemento de forma directa, indicando su indice, sin necesidad de recorrer toda la tabla. (tabla[indice]=4; ó variable=tabla[indice]).
Actualización del array
Cuando trabajemos con arrays, no siempre lo tendremos “completo”. Es decir, podemos tener un vector de 5 elementos en el que la mayor parte del tiempo sólo los elementos con índice 1, 2 y 3 tienen algo significativo. A lo largo del programa, puede darse el caso que prescindamos del tercer elemento o añadamos un dato al elemento con índice 4. Por ello, de algún modo debemos llevar cuenta del número de elementos que nos valen, almacenandolos en las primeras posiciones. Respecto al N comentado al principio del post, diremos que los elementos con datos significativos estarán en el rango 1-N. (tabla[1] primer elemento con dato significativo, tabla[N] último elemento con dato significativo). A medida que vayamos considerando elementos o despreciandolos, iremos actualizando el valor de N.
Adicción a continuación del último elemento
Insertaremos en el último lugar (N+1) si el array no está lleno.
Si N < T
tabla[n+1]=valor
N=N+1
Sino
Escribir “tabla llena”
Fin Si
Inserción en una posición P
En este caso, además de comprobar que la tabla no esta llena, moveremos todos los elementos desde P a N al elemento con índice siguiente, para dejar hueco en la posición P y así poder meter el nuevo valor sin perder ningún dato.
Si N < T
Para j de N a P con incremento -1
tabla[j+1]=tabla[j]
Fin Para
tabla[p]=valor
N=N+1
Sino
Escribir “tabla llena”
Fin Si.
También podríamos haberlo hecho con un bucle mientras en lugar de un para y de P a N en lugar de N a P, pero la filosofía seguiría siendo la misma.
Borrado de un elemento situado en una posición P
En este caso dará lo mismo que el array esté lleno o no, pero no si está vacío. Tras comprobar esto, moveremos hacia la izquierda todos los elementos posteriores a la posición P.
Si N>0
Para j de P a N-1 con incremento 1
tabla[j]=tabla[j]+1
Fin Para
N=N-1
Sino
Escribir “tabla llena”
Fin Si
Búsqueda de un valor x y la posición que ocupa
Aquí debemos tener en cuenta varias cosillas. En primer lugar, consideramos que tenemos una tabla de enteros, ordenada de menor a mayor. La cosa sería
j=1;
Mientras tabla[j]<x y j<N
j=j+1
Fin Mientras
Si tabla[j]=x Escribir “encontrado x en la posicion j”
Sino Escribir “No encontrado”.
Si la tabla no estuviese ordenada, bastaría cambiar el menor por diferente, en la primera condición del mientras. (Mientras tabla[j]<>x y j<N). Otra forma de hacer esto es utilizar un interruptor: lo inicializamos a false, ponemos la condicion en el mientras de mientras interruptor sea igual a false, si en algún momento del bucle lo encuentra hacemos interruptor=true y fuera del bucle preguntamos por qué condición se ha salido. Pero de la forma mostrada queda más eficiente.
Si la tabla contiene valores repetidos, queremos mostrarlos todos y su posición, haremos algo como:
sw=false
Para j de 1 a N con incremento de 1
Si tabla[j]=x
Escribir “encontrado en posicion j”
sw=true;
Fin Si
Fin Para
Si sw=false
Escribir “No encontrado”
Fin Si
Otro método de búsqueda es la búsqueda binaria o dicotomía, válido sólamente para tablas ordenadas. Se comienza comparando el elemento central de la tabla y, si no es el valor buscado, en función de que sea menor o mayor que el elemento buscado, se coge la mitad inferior o superior y se procede de la misma forma. En tablas muy grandes, es una buena opción, debido a su eficiencia respecto a la búsqueda secuencial.
izq=1
der=N
c=(izq+der)/2
Mientras tabla[c]<>x y izq<der
Si tabla[c]> x entonces der=c-1
Sino izq=c+1
Fin Si
c=(izq+der)/2
Fin MientrasSi tabla[c]=x entonces Escribir “encontrado en la posicion c”
Sino Escribir “No encontrado”
Fin Si
Observa que izq va estrechando el cerco por la izquierda o principio del array y la variable der, lo mismo, pero por la derecha o fin del array. Si te fijas en la segunda condición del mientras, paramos cuando izq y der se mezclan o superponen, o lo que es lo mismo, el cerco se convierte en cero. Dentro del bucle, indicamos la nueva zona del array en la que buscar y finalmente preguntamos si coincide la variable buscada. La esencia de este algoritmo, como puedes intuir, es recursiva. (Bastaría con ir pasando a la función la porción de la tabla a evaluar, siguiendo la misma filosofía. Cuando llegue a recursividad, lo retomaremos)

