Capítulo 14. Algoritmos de ordenación y de búsqueda. 1. Introducción.

Anuncio
Capítulo 14. Algoritmos de ordenación y de búsqueda.
1. Introducción.
2. Métodos de ordenación.
2.1. Método de inserción directa.
2.2. Método de selección directa.
2.3. Método de intercambio directo o de la burbuja.
2.4. Método Quicksort.
3. Métodos de búsqueda.
3.1. Búsqueda directa.
3.2. Búsqueda directa con datos ordenados.
3.3. Búsqueda binaria o dicotómica.
1
1. Introducción.
Uno de los procesos más usuales en el tratamiento de datos es la
ordenación de los mismos. Lógicamente, los datos se ordenan para acelerar su
posterior localización.
Cuando el criterio de ordenación se basa en una variable numérica,
obviamente un número es mayor que otro si su valor es más grande. Cuando
se trata de una variable alfanumérica, una será mayor que otra si por orden
alfabético es posterior. Debe recordarse que el orden que se aplica es el
establecido en el código ASCII. Por ejemplo, el carácter ‘d’ es mayor que el ‘Z’,
ya que las mayúsculas son todas menores que las minúsculas. Por otra parte,
para comparar cadenas de caracteres tenemos la función strcmp() que fue
explicada en un capítulo anterior.
La búsqueda de un dato dentro de un conjunto es otro de los procesos
más habituales en el tratamiento de información. Como vamos a ver, si los
datos están ordenados, la localización de uno de ellos puede acelerarse.
2. Métodos de ordenación.
En todos los métodos que vamos a comentar se supone que tenemos
un array de N elementos y lo queremos ordenar de menor a mayor. El índice
del array se moverá entre 0 y N-1.
Estos métodos podrán aplicarse a estructuras de datos diferentes de los
arrays, como por ejemplo los registros de un fichero, siendo el algoritmo
idéntico y cambiando simplemente los nombres de algunas variables.
2.2. Método de inserción directa.
Consiste en buscar para cada elemento, desde el elemento 0 en
adelante, el puesto que le corresponde entre los elementos ya ordenados.
Cuando se va a localizar el puesto del elemento i, los elementos anteriores del
0 al i-1 ya estarán ordenados.
El proceso sería:
- i vale 0: cuando sólo se considera un elemento (valor 19), está en su puesto.
i=0
1
2
3
4
19
5
13
4
7
- i pasa a 1: consideramos dos elementos; se busca el puesto del elemento i,
es decir del elemento 1 (valor 5); si el puesto es el 0, se desplaza el elemento
0 (valor 19) una posición, insertando el elemento 1 en la posición 0.
0
5
i=1
2
3
4
19
13
4
7
- i pasa a 2: consideramos 3 elementos; se busca el puesto del elemento i, es
decir del elemento 2 (valor 13); el puesto se busca desde la posición 0 hasta la
i-1, o sea desde 0 a 1; al 13 le corresponde el puesto 1, por lo que se desplaza
2
desde esa posición hasta i los elementos del array (sólo el 19 en este ejemplo)
y se inserta el 13 en la posición 1.
0
5
1
i=2
3
4
13 19
4
7
- i pasa a 3: consideramos 4 elementos; se busca el puesto del elemento i, es
decir del elemento 3 (valor 4); el puesto se busca desde la posición 0 hasta la
i-1, o sea desde 0 a 2; al 4 le corresponde el puesto 0, por lo que se desplaza
desde esa posición hasta i los elementos del array (el 5, el 13 y el 19 en este
ejemplo) y se inserta el 4 en la posición 0.
0
1
4
5
2
i=3
4
13 19
7
- i pasa a 4: consideramos 5 elementos; se busca el puesto del elemento i, es
decir del elemento 4 (valor 7); el puesto se busca desde la posición 0 hasta la
i-1, o sea desde 0 a 3; al 7 le corresponde el puesto 2, por lo que se desplaza
desde esa posición hasta i los elementos del array (el 13 y el 19 en este
ejemplo) y se inserta el 7 en la posición 2.
0
1
2
4
5
7
3
i=4
13 19
- i pasa a 5: como i es igual a N (el número de elementos del array), ya finaliza
el proceso.
Por tanto, se trata de buscar el puesto de N elementos, es decir un
bucle de N iteraciones (i de 0 a N-1). Para cada iteración, es decir para cada
elemento i, debe buscarse su puesto recorriendo el array hasta i, o sea este
bucle usará una j desde 0 a i. Cuando se conozca el puesto de un elemento i,
deberán desplazarse todos los elementos una posición. Los elementos a
desplazar son desde el puesto encontrado hasta i. El elemento i se insertará
en el hueco libre que ha quedado al desplazar los elementos.
Ej. N vale 5.
#define N 5
...
int A[N] = {19, 5, 13, 4, 7};
int i, j, PuestoI, ElementoInsertar;
for (i = 0; i < N; i++) //Para cada elem. del array
{
PuestoI = 0; //En principio el puesto es 0
for (j = 0; j < i; j++)
if (A[i] > A[j]) //Cada vez que el elem. es
PuestoI++;
//mayor, tiene un puesto más.
ElementoInsertar = A[i]; //Usa variable auxiliar.
3
for (j = i-1; j >= PuestoI; j--) //El bucle debe ir
A[j+1] = A[j];
//hacia atrás (j--), para no
//sobrescribir los elementos.
A[PuestoI] = ElementoInsertar; //Inserta elemento.
}
Este algoritmo también funciona cuando un mismo valor aparece
repetido en el array.
2.2. Método de selección directa.
Este método consiste en recorrer el array completo y para cada iteración
i localizar el menor elemento. Una vez localizado, se intercambia el elemento
menor con el que está en la posición i. Por tanto, se trata simplemente de
buscar el menor elemento entre los que quedan por ordenar, es decir desde i
hasta N-1.
Ej. N vale 5.
#define N 5
...
int A[N] = {19, 5, 13, 4, 7};
int i, j, PuestoMenor, ElementoIntercambio;
for (i = 0; i < N; i++) //Para cada elem. del array
{
PuestoMenor = i; //Inicialmente el puesto es donde
//está el elem. i.
for (j = i+1; j < N; j++)
//Recorre los que quedan
//por ordenar.
if (A[j] < A[PuestoMenor])
PuestoMenor = j;
ElementoIntercambio = A[i];
A[i] = A[PuestoMenor];
A[PuestoMenor] = ElementoIntercambio;
}
Este método no aplica el bucle de desplazamiento que el método
anterior aplicada para cada elemento del array.
2.3. Método de intercambio directo o de la burbuja.
Este método consiste en recorrer el array completo. Cada elemento i
intercambia con el anterior mientras el elemento i sea menor. Esto implica que
para cada elemento i deberá recorrerse el array desde i-1 hasta 0 o hasta que
se encuentre un elemento menor que el i. De este modo cada elemento va
subiendo en el array (burbuja), ya que se va intercambiando con el anterior,
hasta quedar en su puesto. Cuando se va a procesar el elemento i, debe
tenerse en cuenta que todos los elementos anteriores ya estarán ordenados.
4
Ej. N vale 5.
#define N 5
...
int A[N] = {19, 5, 13, 4, 7};
int i, j, Aux; //Variable auxiliar para intercambiar.
for (i = 0; i < N; i++)
{
for (j = i-1; j >= 0 && A[j] > A[j+1]; j--)
{
Aux = A[j]; //Se va intercambiando el elemento
A[j]= A[j+1]; //con el anterior mientras estén
A[j+1] = Aux; //desordenados.
}
}
2.4. Método Quicksort.
Este método está considerado actualmente el mejor algoritmo de
ordenación. Como vamos a ver, se puede implementar usando recursividad.
Consiste en elegir un elemento cualquiera del array, por ejemplo el que
ocupa la posición central, y en una primera pasada colocar todos los
elementos mayores después de ese elemento y todos los elementos menores
antes de dicho elemento central.
Se aplicará de nuevo el proceso a cada mitad del array, llamando a la
misma función, de forma recursiva. Es decir, se ejecuta el mismo algoritmo
sobre el trozo de array donde han quedado los elementos menores y por otra
parte sobre el trozo de array con los elementos mayores.
El algoritmo finaliza cuando el número de elementos del trozo de array
que se va a procesar sea menor o igual a 0, es decir que el trozo de array no
tenga elementos.
Ej. N vale 5.
#define N 5
void QuickSort(int A[], int Desde, int Hasta);
void main(void)
{
int A[N] = {19, 5, 13, 4, 7};
int i;
QuickSort(A, 0, N-1);
}
void QuickSort(int A[], int Desde, int Hasta)
{
int Izq, Der, Mitad, Aux;
Izq = Desde;
5
Der = Hasta;
Mitad = A[(Izq+Der) / 2];
do
{
for ( ;Izq <= Der && A[Izq] < Mitad; Izq++);
for ( ;Der >= Izq && A[Der] > Mitad; Der--);
if (Izq <= Der)
{
Aux
= A[Izq];
A[Izq] = A[Der];
A[Der] = Aux;
Izq++; Der--;
}
} while (Izq <= Der);
if (Izq < Hasta) QuickSort(A, Izq, Hasta);
if (Der > Desde) QuickSort(A, Desde, Der);
}
3. Métodos de búsqueda.
Como en el caso de la ordenación, vamos a suponer que tenemos un
array de N elementos. El índice del array se moverá entre 0 y N-1. El algoritmo
de búsqueda debe indicarnos si un valor determinado está en el array y en qué
posición o si por el contrario no está.
Los métodos de búsqueda que vamos a ver podrán aplicarse a
estructuras de datos diferentes de los arrays. El algoritmo será el mismo, sólo
cambiarán los nombres de algunas variables.
Cuando los datos están ordenados, los algoritmos de búsqueda pueden
ser diferentes y más rápidos.
3.1. Búsqueda directa.
Este es el método más sencillo y consiste en ir comparando el valor
buscado con los sucesivos valores del array, hasta que sean iguales (es
localizado) o hasta que finalice el array (no es localizado). No es necesario que
los datos del array estén ordenados.
Ej. N vale 5.
#define N 5
void main(void)
{
int A[N] = {19, 5, 13, 4, 7};
int i, ValorBuscar;
scanf(“%2d”, &ValorBuscar); fflush(stdin);
for (i = 0; i < N && ValorBuscar != A[i]; i++)
{ ; } //El bucle for sólo incrementa la i.
if (i < N)
printf(“Encontrado en posición %d”, i);
else
6
printf(“No encontrado”);
}
Debe tenerse en cuenta que si se utiliza después del bucle la condición
“if (ValorBuscar == A[i])...” no es del todo correcto, ya que cuando
el valor buscado no se localiza, la i acaba en el valor N y pudiera dar la
casualidad que el valor de A[N] coincidiera con ValorBuscar. A[N] es el valor
después del array en memoria, ya que el array llega hasta N-1.
3.2. Búsqueda directa con datos ordenados.
Si los datos del array están ordenados, por ejemplo de menor a mayor,
cuando se llega a un valor del array que sea mayor que el buscado, la
búsqueda finaliza, ya que los valores sucesivos del array serán aún mayores,
por estar ordenado el array de menor a mayor.
Ej. N vale 5.
#define N 5
void main(void)
{
int A[N] = {19, 5, 13, 4, 7};
int i, ValorBuscar;
scanf(“%2d”, &ValorBuscar); fflush(stdin);
for (i = 0; i < N && ValorBuscar > A[i]; i++);
{ ; } //El bucle for sólo incrementa la i.
if (i < N && ValorBuscar == A[i])
printf(“Encontrado en posición %d”, i);
else
printf(“No encontrado”);
}
3.3. Búsqueda binaria o dicotómica.
Para utilizar este método es necesario que los datos estén ordenados.
El algoritmo consiste en comprobar si el valor es menor o mayor que el valor
central del array o mayor. Si es menor indica que el valor buscado se
encuentra en la primera mitad del array, aplicándose el mismo método a esa
mitad, descartándose la segunda mitad. Si es mayor indica que el valor
buscado se encuentra en la segunda mitad del array y por tanto se aplicará el
mismo método a esa segunda mitad, descartándose la primera mitad. Las
comparaciones con el valor central se hacen hasta que coincida con el valor
buscado o hasta que la mitad del array no tenga elementos.
Ej. N vale 5.
#define N 5
int BusquedaBinaria(int [], int, int, int);
void main(void)
{
int A[N] = {1,6,7,22,25};
int i, ValorBucar;
7
scanf("%d", &Valor); fflush(stdin);
i = BusquedaBinaria(A, 0, N-1, ValorBuscar);
if (i == -1)
printf("\n No localizado");
else
printf("\n Localizado en posición %d", i);
}
int BusquedaBinaria(int A[], int Desde, int Hasta,
int ValorBuscar)
{
int enc = -1;
int izq = Desde, der = Hasta, cen = (der+izq) / 2;
while (ValorBuscar != A[cen] && izq < der)
{
if (ValorBuscar > A[cen])
izq = cen + 1;
else if (ValorBuscar < A[cen])
der = cen - 1;
cen = (der + izq) / 2;
}
if (ValorBuscar == A[cen])
enc = cen;
return(enc);
}
Esta función puede implementarse de forma recursiva.
int BusquedaBinaria(int A[], int Desde, int Hasta,
int ValorBuscar)
{
int enc = -1;
int cen = (Hasta + Desde) / 2;
if (Hasta >= Desde)
{
if (Valor > A[cen])
enc = Buscar(A, cen+1, Hasta, Valor);
else if (Valor < A[cen])
enc = Buscar(A, Desde, cen-1, Valor);
else
enc = cen;
}
return(enc);
}
8
EJERCICIOS - CAPITULO 14:
Realizar los siguientes algoritmos en pseudocódigo y en C.
1. Añadir datos de artículos a un fichero binario con los campos código (long),
descripción y precio. Después ordenarlo por código utilizando el método de
la burbuja.
2. Ordenar el fichero del ejercicio anterior por descripción aplicando el método
de selección directa.
3. Buscar artículos por código en el fichero que está ordenado por código
usando el método de búsqueda directa en datos ordenados.
4. Buscar artículos por descripción aplicando la búsqueda binaria, lógicamente
sobre el fichero ordenado por descripción.
9
Documentos relacionados
Descargar