Sie sind auf Seite 1von 13

Algoritmos de Ordenacin y de Bsqueda

En esta parte del Puzzle I aprenderemos a programar algoritmos para ordenar un conjunto
de datos y tambin a realizar una bsqueda eficaz dentro de un conjunto de datos
ordenado. Los algoritmos de ordenacin y bsqueda son muy utilizados en programacin.

Objetivos
Al finalizar esta actividad sers capaz de:

Ordenar un conjunto de datos utilizando el algoritmo de ordenacin por seleccin


directa.

Buscar un dato dentro de un conjunto ordenado de datos utilizando el algoritmo de


bsqueda binaria o dicotmica.

Motivacin
Con este material aprenders el funcionamiento interno de los algoritmos de ordenacin y
bsqueda. El aprendizaje de estos algoritmos tiene varias implicaciones importantes: en
primer lugar, la bsqueda y la ordenacin son conceptos muy importantes en los entornos de
programacin, ya que una parte importante de los problemas en informtica se ocupa de
dichas tcnicas de una u otra forma. En segundo lugar, entender el funcionamiento de un
algoritmo puede ser un primer paso importante para interpretar su resultado y su coste de
ejecucin (por ejemplo en cuanto a nmero de comparaciones e intercambios necesarios), y
de esta manera poder aplicarlo correctamente. Por ltimo, otro punto importante es que
slo entendiendo el funcionamiento interno de un algoritmo estamos en condicin de
disear nuestros propios algoritmos o modificar los ya existentes.
Finalmente se sugiere una pgina Web para visualizar paso a paso la secuencia de
operaciones de los distintos algoritmos que te ser muy til para acabar de entender las
tcnicas de comparacin e intercambios que utilizan los algoritmos de ordenacin.

Algoritmos de ordenacin:
La problemtica de ordenar un conjunto de datos bajo un determinado criterio es uno de
los ms estudiados en programacin ya que se utiliza ampliamente para resolver un amplio
abanico de aplicaciones de procesamiento de datos.
Como veremos en el siguiente apartado, algunos algoritmos de bsqueda se basan en el
hecho de que el conjunto de datos sobre el que se realiza la bsqueda se ha de ordenar
previamente. Por lo tanto, los algoritmos de ordenacin no tan solo son interesantes por si
mismos, si no que adems facilitan la bsqueda de informacin.
Existen diferentes tipos de algoritmos de ordenacin, pero en funcin del mtodo que
utilizan los podemos clasificar en:

Ordenacin por insercin

Ordenacin por seleccin

Ordenacin por intercambio: Mtodo de la burbuja y Quicksort

En esta actividad estudiaremos en detalle el algoritmo de ordenacin por seleccin directa.


Este algoritmo de ordenacin consiste en dividir el conjunto de datos a ordenar en dos
subconjuntos, el subconjunto ordenado y el que todava est desordenado. En cada
iteracin, el algoritmo selecciona el elemento que cumple el criterio de ordenacin
(creciente o decreciente) del subconjunto desordenado y lo coloca en el subconjunto
ordenado. El algoritmo sigue hasta que el subconjunto de datos desordenado est vaco o
dicho de otra forma hasta que todos los elementos formen parte del subconjunto ordenado.
Supongamos que queremos ordenar de forma creciente un vector de enteros:
int Vector[MAX];
En una determinada iteracin y del algoritmo:

Subconjunto ordenado: Vector[0]........Vector[y-1]

Subconjunto desordenado: Vector[y].......Vector[MAX-1]

Si el criterio de ordenacin es el creciente, en cada iteracin se selecciona el elemento ms


pequeo (de ndice minimo) del subconjunto desordenado (Vector[y] .......
Vector[MAX-1]) y lo intercambiamos con el elemento Vector[y]. De esta forma, el
elemento ms pequeo del subconjunto desordenado pasa a formar parte del subconjunto
ordenado. El algoritmo sigue hasta que el subconjunto de elementos desordenados consta
de cero elementos, es decir, todo el conjunto de datos forma parte del subconjunto
ordenado.
A continuacin se ilustra con un ejemplo la ordenacin por orden creciente de un vector de
6 nmeros enteros utilizando el algoritmo de ordenacin por seleccin. En color azul se
indica el subconjunto de elementos ya ordenados. En color rojo se indica la pareja de
elementos que se intercambian en cada iteracin, es decir, el primer elemento y el
elemento ms pequeo del subconjunto desordenado.

Inicial

Final

15

20

17

17

15

20

15

20 17

15 20

17

15 20

17

15 17 20

Figura 1. Ordenacin por seleccin directa

A grandes rasgos, el algoritmo de ordenacin por seleccin (en el caso de orden creciente)
consiste en:
Para y=1 hasta MAX-1 hacer
Calcular minimo: ndice del elemento ms pequeo entre Vector[y] y Vector[MAX-1]
Intercambiar los elementos Vector[y] y Vector[minimo]
Para calcular el ndice del elemento ms pequeo entre Vector[y] y Vector[MAX-1], que
llamaremos minimo, podemos hacer lo siguiente:
Inicializar el ndice mnimo: minimo=y
Para j=y+1 (ndice primer elemento del subconjunto desordenado) hasta MAX-1 (ltimo)
hacer
si Vector[j]<Vector[minimo] entonces minimo=j
Para intercambiar los elementos Vector[y] y Vector[minimo] podemos hacer lo
siguiente:
temporal = Vector[minimo];
Vector[minimo]= Vector[y];
Vector[y]=temporal;
A continuacin se muestra un programa muy sencillo para ordenar de forma creciente un
vector de nmeros enteros. Antes de continuar prueba de cambiar el criterio de
ordenacin a decreciente y verifica que funciona correctamente.

#include <stdio.h>
#define MAX 5
//Mtodo de Ordenacin por seleccin directa (criterio de
Ordenacin creciente)
void main ()
{
int Vector[MAX];
int y, j, minimo, temporal;
printf ("Mtodo de ordenacin por seleccin directa (criterio
creciente)\n");
printf ("Introduce el vector por ordenar\n");
for (y=0; y<MAX; y++) {
printf ("Vector[%d]=",y);
scanf ("%d", &Vector[y]);
}

for (y=0; y<MAX-1;y++) {


minimo=y;
for (j=y+1; j<MAX; j++)
if (Vector[j]<Vector[minimo]) minimo=j;
temporal=Vector[minimo];
Vector[minimo]=Vector[y];
Vector[y]=temporal;
}
printf ("El vector ordenado de forma creciente:\n");
for (y=0; y<MAX; y++) {
printf ("Vector[%d]=%d\n",y, Vector[y]);
}

A continuacin veremos de forma grfica el funcionamiento de los algoritmos de


ordenacin. Entra a la pgina Web:
http://www.cs.hope.edu/~alganim/ccaa/brummund.html donde encontrars una coleccin
completa de animaciones de los algoritmos de ordenacin (burbuja, insercin, mezcla,
quicksort, seleccin, etc.). Se recomienda que pruebes el funcionamiento y sigas el cdigo
de cada uno de los algoritmos.
La Figura 2 te muestra la pgina principal, en esta actividad probaremos el algoritmo de
seleccin directa, por lo que debes entrar a la opcin que est marcada con una flecha roja
en esta Figura.

Figura 2. Animacin de los algoritmos de ordenacin

En la siguiente pantalla se elige la opcin The Animator:

Figura 3. Animacin del algoritmo de seleccin directa

Posteriormente se elige la opcin SortWindow:

Figura 4. Animacin del algoritmo de seleccin directa (Continuacin)

La siguiente pantalla es una ventana de animacin similar a la que se muestra a continuacin:

Figura 5. Datos a ordenar y cdigo del algoritmo de seleccin directa

La pantalla se divide en cuatro partes, la mitad izquierda tiene columnas azules que
representan los datos a ordenar. Dichas columnas aparecern desordenadas aleatoriamente
cada vez que iniciemos el programa. En la mitad derecha se muestra el cdigo en C++ del
algoritmo de seleccin directa. La lnea de cdigo que est en ejecucin en ese momento se
resaltar en amarillo como veremos posteriormente. La barra superior de la ventana nos
permite cambiar los colores que tendrn las columnas en las distintas etapas del algoritmo.
Por defecto, las columnas ordenadas aparecern en rojo, las columnas analizadas en ese
momento por el algoritmo tendrn color verde y las columnas desordenadas se mostrarn
en azul. Tambin se permite modificar el nmero de columnas a ordenar.
En la barra inferior podemos ver el nmero de comparaciones que va realizando el algoritmo
y el nmero de intercambios. Tambin se puede cambiar el mtodo empleado por el
algoritmo de ordenacin, se recomienda que pruebes el resto de mtodos de ordenacin:
burbuja, insercin, etc.
La Figura 6 muestra el funcionamiento del algoritmo. En amarillo est resaltada la lnea de
cdigo que en ese momento se est ejecutando. Las columnas en verde son los datos que
estn siendo comparados por la lnea de cdigo resaltada en amarillo, en color rojo se
muestran las columnas ya ordenadas y en la barra inferior se puede ver que se han
realizado 83 comparaciones y 4 intercambios de datos.

Figura 6. Algoritmo de seleccin directa en ejecucin

Finalmente, las columnas quedan ordenadas como se muestra en la siguiente Figura, con un
total de 190 comparaciones y 19 intercambios de datos.

Figura 7. Algoritmo de seleccin directa en ejecucin (Continuacin)

Ejercicio: Se recomienda que compruebes cual es el algoritmo que produce el menor nmero
de comparaciones y cual es el que produce el menor nmero de intercambios para el mismo
nmero de columnas.

Algoritmos de Bsqueda:
El problema de buscar una informacin dentro de un determinado conjunto de datos es una
operacin muy frecuente en aplicaciones informticas de proceso de datos. Los algoritmos
de bsqueda los podemos clasificar en dos tipos dependiendo de si el conjunto de datos
sobre el que se realiza la bsqueda est ordenado o no:

Bsqueda secuencial: No requiere un conjunto de datos ordenado

Bsqueda binaria o dicotmica: Requiere un conjunto de datos ordenado

Los algoritmos de bsqueda secuencial son muy sencillos de programar (recuerda el


esquema de bsqueda que has utilizado ya muchas veces) pero tambin muy ineficaces. La
bsqueda sobre un conjunto ordenado es mucho ms eficaz, por esta razn est justificada
la operacin de ordenacin previamente a la bsqueda propiamente dicha sobretodo en el
caso de una gran cantidad de datos.
En esta actividad estudiaremos el algoritmo de bsqueda binaria o dicotmica que requiere
que el conjunto de datos sobre el que se realiza la bsqueda este ordenado bajo algn
criterio. Por ejemplo podemos utilizar el mtodo de ordenacin por seleccin estudiado en
el apartado anterior para ordenar el conjunto de datos previamente a aplicar el algoritmo
de bsqueda dicotmica. El algoritmo es similar al que utilizamos cuando buscamos una
palabra en un diccionario, ya que vamos acotando la bsqueda a aquella parte del diccionario
donde sabemos, que si la palabra existe, la podremos encontrar.
La bsqueda binaria o dicotmica aprovecha el hecho de que el conjunto de datos est
ordenado para realizar la bsqueda nicamente en aquella parte del conjunto de datos
donde, si el dato que se busca existe, seguro que se encuentra. Para cada iteracin del
algoritmo se va reduciendo la zona donde buscar el dato hasta que se encuentra, en el caso
de que exista, o bien hasta que la zona donde se busca queda reducida a cero, en el caso de
que no exista el dato buscado (clave de bsqueda).
En el siguiente grfico se muestra la evolucin del algoritmo de bsqueda binaria sobre un
vector ordenado de forma creciente. En la primera iteracin la zona de bsqueda
comprende todo el vector (limitada por los ndices primero y ultimo). En la segunda
iteracin la bsqueda est limitada a la zona inferior al elemento de ndice mitad (se cumple
la condicin clave<Vector[mitad]). En la tercera iteracin la bsqueda se limita a la
zona superior al elemento de ndice mitad (se cumple la condicin Vector[mitad]<clave).
En cada iteracin se va reduciendo la zona de bsqueda a aquella en la que es encuentra la
clave de bsqueda (si existe). El algoritmo se acaba al encontrar la clave de bsqueda o
bien cuando la zona de bsqueda queda reducida a cero (corresponde al caso de no
encontrar la clave de bsqueda).

clave < Vector[mitad]

Vector[mitad] < clave

primer
primero

. . . .

primer
primero

mitad

primer
primero
mitad

ltim
ltimo

mitad

ltim
ltimo

. . . .

ltim
ltimo

Figura 7. Bsqueda binaria o dicotmica

Supongamos que queremos buscar un dato, que llamaremos clave de bsqueda, en un


vector de elementos de tipo TipusDada ordenado de forma creciente (en cada caso habr
que definir el TipusDada):
TipusDada Vector[MAX];
TipusDada clave;
A grandes rasgos el algoritmo de bsqueda binaria consiste en:
Inicializar los ndices: primero, ultimo y mitad
Repetir
Calcular el ndice mitad
Averiguar en que mitad del vector se ha de seguir buscando la clave
Actualizar los ndices primero y ultimo adecuadamente en cada caso
hasta que se ha encontrado la clave o fin de la bsqueda
Inicialmente los ndices primero y ltimo tienen los valores:
primero = 0;
ultimo = MAX-1;
El ndice del elemento mitad se puede calcular:
mitad = (primero + ultimo) / 2
Para saber en que mitad del vector se ha de seguir buscando la clave, tenemos que saber si
la clave se encuentra en la mitad superior o inferior del vector al elemento de ndice mitad:
-Mitad superior del vector al elemento de ndice mitad:
Si clave>Vector[mitad] entonces primero=mitad+1
-Mitad inferior del vector al elemento de ndice mitad:
Si clave<=Vector[mitad] entonces ultimo=mitad-1
El algoritmo de bsqueda binaria puede acabar por dos motivos:

Se ha encontrado la clave de bsqueda en el vector:

clave = Vector[mitad]

Hemos finalizado la bsqueda sin encontrar la clave de bsqueda. Eso significa


que la zona donde buscar la clave ha quedado reducida a cero. Es decir, los ndices
primero y ultimo se han cruzado sin encontrar la clave.
primero > ultimo

A continuacin es muestra un programa muy sencillo para buscar el valor clave dentro de
un vector de nmeros enteros ordenado de forma creciente. Este programa slo funciona
correctamente si introducimos el vector ordenado de forma creciente.
#include <stdio.h>
#define MAX 5
//Bsqueda binaria o dicotmica
//Vector ordenado de forma creciente
void main ()
{
int Vector[MAX];
int y, clave, primero, ultimo, mitad;
printf ("Bsqueda binaria o dicotomica\n");
printf ("Introduce el vector ordenado de forma creciente\n");
for (y=0; y<MAX; y++) {
printf ("Vector[%d]=",y);
scanf ("%d", &Vector[y]);
};
printf ("Introduce el valor a buscar: ");
scanf ("%d", &clave);
primero=0;
ultimo=MAX-1;
mitad=(primero+ultimo)/2;
do {
if (clave>Vector[mitad])
primero=mitad+1;
else
ultimo=mitad-1;
mitad=(primero+ultimo)/2;
} while (!((Vector[mitad]==clave) || (primero>ultimo)));
if (Vector[mitad]==clave)
printf ("Se ha encontrado el valor %d y su ndice es %d\n", clave,
mitad);
else
printf ("No se ha encontrado el valor %d\n", clave);
}

Introduce un vector ordenado de forma creciente de 5 nmeros enteros y comprueba que


el programa no funciona correctamente en el caso de que el ndice del elemento que
buscamos corresponda con el elemento de la mitad (ndice 2 en este caso). Modifica el
programa para que funcione correctamente. Antes de continuar prueba de cambiar el
programa para que tambin funcione correctamente si introducimos el vector ordenado de
forma decreciente.

Ejercicios
Se tienen las siguientes estructuras de datos para representar la informacin que se
utiliza en un invernadero:
struct tipo_planta {
tipusText nombre;
tipusText pais_origen;
int num_refer;
int precio;
};
typedef struct tipo_planta

//
//
//
//

Nombre de la planta
Pas de origen de la planta
Nmero de referencia que tiene la planta
Precio de venta

planta;

struct tipo_vector {
int num_elems;
// nmero total de plantas
planta element[MAX_NUM_ELEMS];
};
typedef struct tipo_vector Tvector;
Primero crea un procedimiento que te permita leer del teclado los datos de la planta
(nombre, pas de origen, nmero de referencia y precio) y que los aada a la estructura
Tvector. Puedes utilizar la siguiente cabecera:
void agregar_planta (Tvector *v);
Posteriormente crea un procedimiento que te permita desplegar en pantalla el contenido de
la lista completa de plantas (incluyendo la recin insertada). Puedes utilizar la siguiente
cabecera:
void pintar_plantas (Tvector *v);
1.

Aade un procedimiento con la siguiente cabecera:

void ordena_seleccion (Tvector *v, int opcion);


Este procedimiento ordena la lista de plantas contenida en el archivo invernadero.txt, se
debe utilizar el algoritmo de seleccin. La variable opcion permite escoger el tipo de
ordenacin (ascendente o descendente). La ordenacin se realizar con respecto al campo
del nombre de la planta y en caso de que dos plantas tengan el mismo nombre dichas plantas
debern aparecer ordenadas de acuerdo al pas de origen de la planta.
2. Aade una funcin con la siguiente cabecera:
int oferta (Tvector *v);
Esta funcin pide por teclado el nombre y el pas de origen de la planta. Posteriormente
busca en la lista la planta que tenga el nombre y el pas igual y le hace un descuento del 10%
del precio actual. Considera que como mximo solo puede existir una planta que tenga el
nombre y el pas igual. El vector esta ordenado y debes utilizar el mtodo de bsqueda
dicotmica. La funcin debe visualizar en pantalla los datos de las plantas a las que se le
cambi el precio y la lista de plantas completa actualizada.
3. Aade un procedimiento con la siguiente cabecera:
void cambia_vector (Tvector *v);

Esta funcin elimina del vector las plantas que tengan el menor precio y las inserta en un
vector nuevo. La funcin devuelve en pantalla los datos de las plantas eliminadas y la lista
de plantas completa actualizada.

Das könnte Ihnen auch gefallen