1. Universidad de Alcalá
Departamento de Automática
Área de Arquitectura y Tecnología de Computadores
Laboratorio de Sistemas Informáticos
GITT, GIT, GIST y GIEC
PRÁCTICA 3
ARRAYS, ORDENACIÓN y BÚSQUEDA
OBJETIVOS
• Manejo de arrays
• Utilizar métodos de ordenación y de búsqueda en arrays
• Fusión de arrays ordenados
TEMPORIZACIÓN
• Inicio de la práctica: Semana del 15 de Octubre
• Tiempo de desarrollo de la práctica: finalizarla antes del examen parcial 2
• Evaluación: ver fechas en http://atc1.aut.uah.es.
BIBLIOGRAFÍA
C/C++ Curso de programación
Autor: Fco. Javier Ceballos
Editorial: RA-MA.
Práctica 3 – Arrays, ordenación y búsqueda Página 1
2. Universidad de Alcalá
Departamento de Automática
Área de Arquitectura y Tecnología de Computadores
Laboratorio de Sistemas Informáticos
GITT, GIT, GIST y GIEC
1. Introducción
Un array (matriz) es una colección de variables del mismo tipo referenciadas por un nombre común
seguido de un índice que indica la posición del elemento dentro del array. Los elementos de un
array se almacenan en posiciones contiguas de memoria. La dirección más baja corresponde al
primer elemento y la más alta al último. En un array de N elementos, el índice del primero es 0 y el
índice del último es N-1.
El siguiente programa define un array de diez elementos de tipo entero, almacena en él diez
números leídos desde teclado y finalmente visualiza el array por pantalla:
#include <stdio.h>
#define MAX 10
int main ()
{
int numeros[MAX], i;
for (i=0; i<MAX; i++)
{
printf ("Introduzca el elemento %d: ", i);
scanf ("%d", &numeros[i]);
}
printf ("n**** LISTADO DE LOS NUMEROS LEIDOS ******nn");
for (i=0; i<MAX; i++)
printf (" %d, ", numeros[i]);
printf ("nn");
return 0;
}
2. Ejercicios a realizar
2.1. Realice un programa que, dada una fecha, calcule el número de días que quedan hasta final de
año. Por ejemplo: para el 12 10 1995, el resultado correcto sería 80 días. Además, el programa
deberá verificar que la fecha introducida es una fecha válida.
Utilice un array dias_mes de 12 elementos que contenga el número de días que tiene cada mes del
año.
Tenga también en cuenta que son bisiestos todos los años múltiplos de 4, excepto los múltiplos de
100, que sólo son bisiestos si son múltiplo de 400. Por ejemplo: los años 1999, 2003 y 2100 no son
bisiestos, mientras que los años 2000 y 2004 sí son bisiestos. Explicación: 1999 y 2003 ni siquiera
son múltiplos de 4, y 2100 es múltiplo de 4, pero es múltiplo de 100 sin ser múltiplo de 400. Por
otro lado, 2000 es múltiplo de 400 (y de 4, claro) y 2004 es múltiplo de 4 sin ser múltiplo de 100.
El seudocódigo podría ser:
Pedir día mes y año
Averiguar si año es bisiesto o no
Lo es si: (es múltiplo de 400 _O_ (es múltiplo de 4 _Y_ NO de 100))
Actualizar días_mes[febrero] (28 o 29)
Comprobar que mes es válido (enero, febrero, ... o diciembre)
Comprobar que día está entre 1 y dias_mes[mes]
Sumar los días de los meses desde mes hasta fin de año
Restar día
Mostrar resultado
Práctica 3 – Arrays, ordenación y búsqueda Página 2
3. Universidad de Alcalá
Departamento de Automática
Área de Arquitectura y Tecnología de Computadores
Laboratorio de Sistemas Informáticos
GITT, GIT, GIST y GIEC
2.2. Realice un programa que, dada una cantidad de euros (sin céntimos), la desglose en el menor
número posible de billetes y monedas. Por ejemplo: 1747 euros se desglosan en 3 billetes de 500
euros, 1 billete de 200 euros, 2 billetes de 20 euros, 1 billete de 5 euros, y una moneda de 2 euros.
Utilice para la resolución del problema un array que almacene en orden descendente el valor de los
distintos billetes y monedas existentes (billetes de 500 euros, de 200 euros, de 100 euros, de 50
euros, de 20 euros, de 10 euros y de 5 euros; monedas de 2 euros y de 1 euro).
El seudocódigo podría ser:
Pedir cantidad
i = 0
MIENTRAS (cantidad > 0)
n = cantidad / valor[i] (división entera)
cantidad = resto de la división anterior
SI (n > 0)
Mostrar "n billetes/monedas de valor[i] euros"
Incrementar i
2.3. Se desea pagar ciertas cantidades en efectivo a diferentes personas, y para ello hay que hacer
previamente un aprovisionamiento de dinero suelto. Realice un programa que, dada una serie de
cantidades de euros (sin céntimos), calcule la suma de sus desgloses en billetes y monedas. No se
trata de mostrar varios desgloses por separado, ni de calcular el desglose de la suma, sino la suma
de los desgloses. Es decir, el programa debe mostrar las cantidades totales de los distintos tipos de
billetes y monedas necesarios para poder pagar por separado las cantidades dadas. Por ejemplo, si
las cantidades son 15 euros, 17 euros y 18 euros, hacen falta tres billetes de 10 euros, tres billetes
de 5 euros, dos monedas de 2 euros, y una moneda de 1 euro. Nótese que un billete de 50 euros no
serviría para pagar las tres cantidades por separado.
Se recomienda realizar los desgloses con un algoritmo similar al del ejercicio anterior, pero no
mostrar los resultados sobre la marcha, y en lugar de ello, acumular los números de billetes y
monedas en un segundo array.
El seudocódigo podría ser:
Pedir número de cantidades num
REPETIR num VECES
Pedir cantidad
i = 0
MIENTRAS (cantidad > 0)
n = cantidad / valor[i] (división entera)
cantidad = resto de la división anterior
billetes[i] = billetes[i] + n
Incrementar i
Mostrar desglose almacenado en el array billetes
2.4. Realice un programa que calcule la media de las estaturas de una clase de n alumnos. Además
deberá calcular y visualizar cuántos son más altos que la media, cuantos más bajos que la media y
cuántos son iguales a la media. Suponga que el número máximo de alumnos es 200.
Preguntar cuántos alumnos hay en la clase
Pedir las estaturas
Calcular la media
Contar altos y bajos
Mostrar resultados
Práctica 3 – Arrays, ordenación y búsqueda Página 3
4. Universidad de Alcalá
Departamento de Automática
Área de Arquitectura y Tecnología de Computadores
Laboratorio de Sistemas Informáticos
GITT, GIT, GIST y GIEC
2.5. Realice un programa que lea un número impar de valores y dé como resultado la mediana. La
mediana de una lista de n números se define como: el valor que es menor o igual que los valores
correspondientes a la mitad de los números, y mayor o igual que los valores correspondientes a la
otra mitad. Por ejemplo, la mediana de: 16 12 99 95 18 87 10 es 18, porque este valor es menor
que 99, 95, 87 (mitad de los números) y mayor que 16,12 y 10 (otra mitad). En este apartado no
está permitido emplear ningún método de ordenación. Suponga que la cantidad de valores nunca es
mayor que 15.
El seudocódigo podría ser el siguiente:
Preguntar cuántos números quiere introducir el usuario
Pedir los números y guardarlos en un array
REPETIR CON CADA UNO
Contar, entre los demás, cuántos son >= y cuántos son <=
Si las cantidades coinciden, el elegido es la mediana
2.6. Realice un programa que, dada una serie de n números (100 números como máximo) de tipo
double (coma flotante de doble precisión), los ordene de mayor a menor mediante el algoritmo de
la burbuja. A continuación se describe dicho algoritmo para el caso de la ordenación de menor a
mayor (la más habitual):
El algoritmo de la burbuja opera intercambiando elementos contiguos del array cuando éstos no
están ordenados entre sí.
Se comienza comparando el primer elemento con el segundo, e intercambiándolos si el primero es
mayor que el segundo; entonces se compara el segundo con el tercero, y así sucesivamente hasta
llegar al final. Llamaremos a esto una “pasada”.
Nótese que, al comparar e intercambiar (o no) el primero con el segundo, el mayor de los dos queda
en la segunda posición. Inmediatamente se compara e intercambia (o no) con el tercero, y entonces
el mayor de los tres queda tercero y así sucesivamente, de modo que al llegar al final, el elemento
mayor de todos ya está en su posición definitiva.
El resto de elementos puede haber quedado ordenado o no. A continuación se realizará otra pasada,
pero esta vez llegando sólo hasta el penúltimo elemento. Después otra pasada un poquito más corta,
luego otra...
Si a lo largo de una pasada no se realiza ningún intercambio, se puede concluir que el array ya está
ordenado y no realizar ninguna pasada más. En el peor de los casos, todas las pasadas requerirán
algún intercambio y el algoritmo realizará pasadas cada vez más cortas hasta concluir con una
última pasada de una sola comparación-intercambio (el primer elemento con el segundo). En otras
palabras, la primera pasada deja colocado al último elemento, la segunda al penúltimo, la tercera al
antepenúltimo, y así sucesivamente hasta colocar al tercero, y finalmente a los dos primeros. En
total, para un array de n elementos, se realizarán como máximo n-1 pasadas y n*(n-1)/2
operaciones de comparación-intercambio.
La condición de fin se puede detectar contando el número de intercambios en cada pasada. El
contador se pone a cero al principio de cada pasada, y se incrementa cada vez que se hace un
intercambio. Si al final de la pasada sigue estando a cero, se puede parar.
En realidad no interesa saber cuántos intercambios se ha hecho en una pasada. Basta saber si se ha
hecho alguno o no. Por lo tanto, en vez de un contador, se puede usar una bandera: se pone a cero
al principio de la pasada, y se le asigna el valor uno al hacer un intercambio.
Práctica 3 – Arrays, ordenación y búsqueda Página 4
5. Universidad de Alcalá
Departamento de Automática
Área de Arquitectura y Tecnología de Computadores
Laboratorio de Sistemas Informáticos
GITT, GIT, GIST y GIEC
El seudocódigo podría ser el siguiente:
Preguntar cuántos números (n) quiere introducir el usuario
Pedir los n números y guardarlos en un array
REPETIR como máximo n-1 veces:
bandera = 0
PASADA: Recorrer array desde el principio, comparando elementos
contiguos e intercambiándolos (y bandera=1) si es
necesario. Cada pasada se puede hacer un poco más corta
que la anterior.
SI bandera == 0
Ya están ordenados. Salir del bucle.
Mostrar los n números ordenados
La versión final del programa tendrá dos funciones: main y ordenar. La función ordenar no
devolverá nada y tendrá dos parámetros: la matriz a ordenar y su número de elementos.
2.7. Realice un programa que implemente el método de búsqueda binaria (descrito a continuación).
Para aplicarlo será necesario disponer de un array de enteros ordenados de menor a mayor (100
números como máximo). Pedir los números y después, ordenarlos utilizando la función ordenar
del programa anterior.
La búsqueda binaria se apoya en el hecho de que los datos están ordenados, para localizar el
elemento buscado en muy pocos pasos. Se busca en un intervalo del array (inicialmente todo el
array) y se va reduciendo ese intervalo a la mitad en cada paso. Para ello, basta comparar el
elemento buscado con el elemento situado en el centro del intervalo de búsqueda. Si el elemento
buscado es mayor, hay que continuar la búsqueda por la mitad superior (la inferior queda
descartada junto con el elemento comparado). Si es menor, hay que continuar por la mitad inferior.
Si es igual, ya se ha encontrado el elemento buscado. Si el intervalo se consume completamente sin
que se haya encontrado, entonces el elemento no está en el array (¡o el array no estaba bien
ordenado!).
El seudocódigo podría ser el siguiente:
Preguntar cuántos números (n) quiere introducir el usuario
Pedir los n números y guardarlos en un array
Ordenarlos, o verificar que el usuario los ha introducido ordenados
Pedir el valor (x) a buscar
bajo = 0
alto = n-1
MIENTRAS (bajo <= alto)
central = (alto + bajo) / 2 (división entera)
SI (x == número[central])
¡Éxito! Mostrar al usuario la posición central
Salir del programa
SI (x > número[central])
bajo = central + 1
SI (x < número[central])
alto = central - 1
¡Fracaso! El número buscado no estaba en el array
La versión final del programa tendrá tres funciones: main, ordenar y buscar. La función buscar
tendrá dos parámetros: la matriz a ordenar y su número de elementos, y devolverá el índice en la
matriz correspondiente al valor buscado o -1 si no se encontró.
Práctica 3 – Arrays, ordenación y búsqueda Página 5
6. Universidad de Alcalá
Departamento de Automática
Área de Arquitectura y Tecnología de Computadores
Laboratorio de Sistemas Informáticos
GITT, GIT, GIST y GIEC
2.8. Realice un programa que fusione dos arrays ordenados en uno solo. Lógicamente, el número
de elementos resultantes será igual a la suma de los números de elementos de los arrays originales.
El programa deberá realizar la operación en el menor tiempo posible. Este requisito obliga a
descartar la ordenación como posible solución al problema. Es decir, que copiar los arrays uno a
continuación del otro, y ordenar el resultado no es una solución válida.
En realidad, dado que los arrays originales están ordenados, hay una solución más directa que
resuelve el problema en una sola pasada. Se trata de ir copiando los elementos en orden, según se
avanza por los arrays. A cada paso se escoge el menor de los dos elementos disponibles, y se
avanza en el array que lo contiene (y no en el otro).
Al igual que en el ejercicio anterior, se puede optar por pedir los datos al usuario y ordenarlos (en
los arrays originales, no juntos), o exigir al usuario que introduzca los datos ya ordenados y
verificarlo.
El seudocódigo podría ser el siguiente:
Preguntar el tamaño (m) del primer array (máximo 50)
Preguntar el tamaño (n) del segundo array (máximo 50)
Pedir los m números y guardarlos en el array A
Ordenarlos, o verificar que el usuario los ha introducido ordenados
Pedir los n números y guardarlos en el array B
Ordenarlos, o verificar que el usuario los ha introducido ordenados
i = j = k = 0
MIENTRAS (i<m _Y_ j<n)
SI A[i] <= B[j]
C[k] = A[i]
Incrementar i y k
SI NO
C[k] = B[j]
Incrementar j y k
MIENTRAS (i<m)
C[k] = A[i]
Incrementar i y k
MIENTRAS (j<n)
C[k] = B[j]
Incrementar j y k
Mostrar el array resultante C
Práctica 3 – Arrays, ordenación y búsqueda Página 6