Você está na página 1de 15

Algoritmos y estructura de datos I

Pgina 1

UNIVERSIDAD CATLICA DE SANTA MARA PROGRAMA PROFESIONAL DE INGENIERA DE SISTEMAS

SESIN 05:

ORDENACIN Y BSQUEDA. Parte II


I OBJETIVOS
Explicar los principales mtodos de ordenamiento. Explicar los principales mtodos de bsqueda. Aplicar mtodos de ordenamiento y bsqueda a la solucin de problemas reales.

II TEMAS A TRATAR
Mtodo de ordenacin Shell Mtodo de ordenacin por Quicksort. Mtodo de bsqueda binaria

III MARCO TEORICO


ORDENACIN POR INCREMENTOS (SHELL SORT) Debe su nombre a su inventor Donald Shell. Modifica los saltos contiguos del mtodo de burbuja a saltos variables que se achican. Inicia con Intervalo del orden n/2 y luego tiende a 1. Algoritmo Dividir lista original en n/2 grupos de 2 elementos, Intervalo entre los elementos: n/2. Clarificar cada grupo por separado, comparando parejas de elementos. Si No Estn Ordenados Entonces CAMBIARLOS. Dividir lista original en n/4 grupos de 4 elementos, Intervalo entre los elementos: n/4. Continuar sucesivamente hasta que el intervalo==1. La ordenacin por insercin puede resultar lenta pues slo intercambia elementos adyacentes. As, si por ejemplo el elemento menor est al final del vector, hacen falta n pasos para colocarlo donde corresponde. El mtodo de Incrementos es una extensin muy simple y eficiente del mtodo de Insercin en el que cada elemento se coloca casi en su posicin definitiva en la primera pasada. El algoritmo consiste bsicamente en dividir el vector a en h subvectores: a[k], a[k+h], a[k+2h], a[k+3h], ... y ordenar por insercin cada uno de esos subvectores (k=1,2,...,h1). Un vector de esta forma, es decir, compuesto por h subvectores ordenados intercalados, se denomina h-ordenado.

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 2

Haciendo h-ordenaciones de a para valores grandes de h permitimos que los elementos puedan moverse grandes distancias dentro del vector, facilitando as las h-ordenaciones para valores ms pequeos de h. A h se le denomina incremento. Con esto, el mtodo de ordenacin por Incrementos consiste en hacer h-ordenaciones de a para valores de h decreciendo hasta llegar a uno. El nmero de comparaciones que se realizan en este algoritmo va a depender de la secuencia de incrementos h, y ser mayor que en el mtodo clsico de Insercin (que se ejecuta finalmente para h = 1), pero la potencia de este mtodo consiste en conseguir un nmero de intercambios mucho menor que con la Insercin clsica. El procedimiento presentado a continuacin utiliza la secuencia de incrementos h = ..., 1093, 364, 121, 40, 13, 1. Otras secuencias pueden ser utilizadas, pero la eleccin ha de hacerse con cuidado. Por ejemplo la secuencia ..., 64, 32, 16, 8, 4, 2, 1 es muy ineficiente pues los elementos en posiciones pares e impares no son comparados hasta el ltimo momento. En el ejercicio 2.7 se discute ms a fondo esta circunstancia. ORDENACIN SHELL: EJEMPLO Ordenar los siguientes datos por el mtodo de SHELL

SOLUCIN Lista Original n=7 Intervalo Inicial: n/2=7/2=3.5=3 Intervalos Siguientes=IntervaloAnterior/2 Se compara a[i] con a[i+Intervalo] Si No Estn Ordenados Entonces CAMBIARLOS (6, 2)

(5, 4)

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I (6,0)

Pgina 3

(2,0)

Lista Original n=7 Intervalo Inicial: n/2=3/2=1.5=1 Intervalos Siguientes=IntervaloAnterior/2 Se compara a[i] con a[i+Intervalo] Si No Estn Ordenados Entonces CAMBIARLOS (4, 2)

(4,3)

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I


ORDENACIN SHELL: CODIFICACIN EN C/C++ void ordenacionShell (int A[], int n) { int i, j, intervalo, temp; intervalo = n/2; while (intervalo > 0) { for (i=intervalo; i < n; i++) { j = i; temp = A[i]; while ((j >= intervalo) && (A[j-intervalo] > temp)) { A[j] = A[j - intervalo]; j = j - intervalo; } A[j] = temp; } intervalo = intervalo/2; } }

Pgina 4

El 1er while: Log2n El for: n F(n)=n*Log2(n) Shell.cpp


#include<iostream> #include<stdlib.h> #define N 7 using namespace std; void ordenacionShell (int A[], int n) { int i, j, intervalo, temp; intervalo = n/2; while (intervalo > 0) { for (i=intervalo; i < n; i++) { j = i; temp = A[i]; while ((j >= intervalo) && (A[j-intervalo] > temp)) { A[j] = A[j - intervalo]; j = j - intervalo; } A[j] = temp; } intervalo = intervalo/2; } } void mostrar(int a[],int n) { int i; for(i=0;i<n;i++) { cout<<a[i]<<","; } } int main(char *arg) { int v[]={6,1,5,2,3,4,0}; ordenacionShell(v,N); mostrar(v,N); cout<<endl<<endl;

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I


system("PAUSE");; return 0; }

Pgina 5

Propuestos Ordenar manualmente usando el mtodo Shell la siguiente secuencia: 10,5,2,6,7,3,8,9,14,34,11,14

QUICKSORT
Desarrollado por C. A. R. Hoare en 1962. Es el algoritmo ms rpido conocido 2 En promedio es O(N log N), pero el peor case es O(N ). Es posible hacer que el peor caso sea exponencialmente improbable. Se basa en el concepto de particin. En una particin se escoge un pivote y se colocan los elementos mayores que el pivote en la parte superior del arreglo y los menores en la inferior. Se aplica este concepto en forma recursiva para obtener el algoritmo PARTICIN DE ARREGLOS CON QUICKSORT 1) Se designa arbitrariamente a[r] como elemento de particin. 2) Se recorre a partir del lado izquierdo hasta encontrar un elemento mayor al elemento de particin. 3) Se recorre a partir del lado derecho hasta encontrar un elemento menor al elemento de particin. 4) Se intercambian los elementos que detuvieron los recorridos.

SOBRE LA ELECCIN DEL PIVOTE. Si se elige como pivote el primer elemento o el ltimo, lo cual es fcil de realizar, se tendr mal funcionamiento si el arreglo est ordenado en forma inversa. Sin embargo el comportamiento es bueno, si el orden original es aleatorio. Si el cursor del pivote se elige en forma aleatoria, existir buen comportamiento; sin embargo la generacin repetida de los nmeros aleatorios puede requerir un tiempo no despreciable. Encontrar la mediana de los nmeros, que sera una mejor opcin, tambin aumenta los costos, debido a la complejidad de encontrar la mediana. Una alternativa es escoger la mediana de tres nmeros. Si l y r son los cursores del primer y ltimo elemento del arreglo, para formar el tercer nmero se toma el valor central. Es decir, se toma la mediana de los tres nmeros con cursores: l, r y (l+r)/2. En el algoritmo a continuacin se escoge como pivote, el valor central del arreglo .
void qsort(int l, int r) { int i=l, j=r; registro piv=a[(l+r)/2)]; do { while(a[i].clave < piv.clave) i++; while( piv.clave < a[j].clave)

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I


j--; if( i<=j { swap(i, j) ; i++; j--; } }while(i<=j); if( l < j) qsort( l, j); if( i< r ) qsort( i, r); }

Pgina 6

Se inicia una particin luego se aplica el mismo proceso a las dos particiones. Las particiones menores, vuelven a generar dos particiones y as sucesivamente hasta que la particin tiene un solo tem, en este caso no se generan nuevas recursiones. Para ordenar un arreglo se invoca: qsort(0, N-1) para un arreglo de N tems. Produce un ordenamiento ascendente. QUICKSORT EN RESUMEN Algoritmo divide-and-conquer. Se basa en una operacin de particin: elegir un elemento pivote, mover los elementos ms pequeos, adelante de ste y los elementos ms grandes atrs de l. La operacin de particin se puede hacer eficiente en tiempo lineal y en su lugar. Las listas de elementos mayores y menores se procesan recursivamente. Implementaciones de quicksort son tpicamente inestables y algo complejas. Se encuentra entre los algoritmos de ordenamiento ms rpidos en prctica. El desempeo de quicksort depende en gran parte en la eleccin de un buen elemento de particin o pivote. Una mala eleccin de pivote puede resultar en un desempeo mucho ms lento O(n2), pero si en cada paso elegimos la mediana como el pivote, entonces funciona en O(n log n). ORDENACIN QUICKSORT: EJEMPLO Ordenar los siguientes datos por el mtodo de QUICKSORT

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 7

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 8

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 9

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 10

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 11

PROPUESTOS Ordenar manualmente usando el mtodo de QUICKSORT la siguiente secuencia.

Quicksort.cpp
#include<iostream> #include<stdlib.h> #define N 7 using namespace std;

void qsortnw(int A[], int l, int r) { int i=l, j=r; int temp; int piv=A[(l+r)/2]; do { while ( A[i] < piv) i++; while( piv < A[j]) j--; if( i<=j) { if (i!=j) { temp=A[i];

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I


A[i]= A[j]; A[j]=temp; } i++; j--; } } while(i<=j); if( l < j) { qsortnw( A, l, j); //izq++; }; if( i < r ) { qsortnw( A, i, r); //der++; }; } void mostrar(int a[],int n) { int i; for(i=0;i<n;i++) { cout<<a[i]<<","; } } int main(char *arg) { int v[]={6,1,5,2,3,4,0}; qsortnw(v,0, N-1); mostrar(v,N ); cout<<endl<<endl; system("PAUSE");; return 0; }

Pgina 12

BSQUEDA
Encontrar una CLAVE especifica dentro de un Almacn, donde existe un campo con la clave que se referencia. Si est en la lista, informa su posicin. Si el Almacn Est Ordenado la bsqueda puede ser ms eficiente. TIPOS DE BSQUEDA Secuencial: Busca la clave explorando un elemento despus de otro. Es la nica forma de encontrarlo cuando la Lista no est Ordenada por la Clave de Bsqueda. Eficiencia del Orden de F(n)=n. Binaria: En listas Ordenadas por la clave de Bsqueda es el mejor mtodo. Se sita la lectura al centro de la lista y se lo comprueba contra la clave. Si clave < a[central]: Buscar entre inferior y central1 Si clave > a[central]: Buscar entre central+1 y superior Eficiencia del Orden F(n)=log2n BSQUEDA BINARIA: CODIFICACIN EN C/C++
int busquedaBin(int lista[], int n, int clave) { int central, bajo, alto, valorCentral; bajo = 0; alto = n-1; while (bajo <= alto) { central = (bajo + alto)/2; /* ndice de elemento central */ valorCentral = lista[central];/* valor del ndice central */ if (clave == valorCentral) return central; /* devuelve posicin */

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I


else if (clave < valorCentral) alto = central -1; /*sublista inferior*/ else bajo = central + 1; /* ir a sublista superior */ } return -1; /* elemento no encontrado */ }

Pgina 13

Eficiencia del Orden F(n)=log2n

BusquedaBinaria.cpp
#include<iostream.h> #include<stdlib.h> #define N 7 int busquedaBin(int lista[], int n, int clave) { int central, bajo, alto, valorCentral; bajo = 0; alto = n-1; while (bajo <= alto) { central = (bajo + alto)/2; /* ndice de elemento central */ valorCentral = lista[central];/* valor del ndice central */ if (clave == valorCentral) return central; /* devuelve posicin */ else if (clave < valorCentral) alto = central -1; /*sublista inferior*/ else bajo = central + 1; /* ir a sublista superior */ } return -1; /* elemento no encontrado */ } void mostrar(int a[],int p) { cout<<"encontrado: "<<a[p]<<","; }

int main(char *arg) { int v[]={6,1,5,2,3,4,0}; int pos; pos=busquedaBin(v,N,4); mostrar(v,pos); cout<<endl<<endl; system("PAUSE");; return 0; }

PROPUESTOS Buscar manualmente usando el mtodo de Bsqueda binaria el siguiente valor: 34.

10, 5, 2, 6, 7, 3, 8, 9,14,34,11,1,4

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 14

IV EJERCICIOS
1. Desarrolle un programa el lenguaje ANSI C que dados dos arreglos A y B cada uno con 10 elementos: Llene los arreglos A y B. Ordene ascendentemente A y B por los mtodos shellsort y quicksort. Mezcle ordenadamente los elementos de A y B en un arreglo C el cual no debe contener elementos repetidos. 2. Dado un arreglo de tamao 30 que almacena nmeros reales, desarrolle un programa el lenguaje ANSI C que llene el arreglo. Adems, debe permitir ordenar los elementos que estn en las posiciones pares en forma ascendente y los elementos que estn en las posiciones impares en forma descendente utilizando el algoritmo QUICKSORT. Observaciones: No utilice otro arreglo para dejar ordenado los elementos. No ordene los valores al momento de ingresarlos. 3. Modificar los algoritmos Quicksort y Mezcla de forma que sustituyan las llamadas recursivas por llamadas al procedimiento Seleccin cuando el tamao del vector a ordenar sea menor que una cota dada M. 4. Realizar implementaciones iterativas para los procedimientos Quicksort y Mezcla. Estudiar sus complejidades (espacio y tiempo) y comparar los resultados con los obtenidos para las versiones recursivas. 5. El problema del k-simo elemento: Dado un vector de enteros, queremos encontrar el elemento que ocupara la posicin k si el vector estuviera ordenado en orden creciente (esto es, el k-simo menor elemento). Una primera idea para resolver este problema consiste en ordenar primero el vector y despus escoger el elemento en la posicin k, pero la complejidad de este algoritmo es O(nlogn). Puede hacerse de alguna forma ms eficiente? Considerar la siguiente idea: Utilizar un procedimiento basado en la idea de Quicksort, escogiendo como pivote el elemento en la posicin k del vector.

V CUESTIONARIO
1. Cuales son los mtodos de bsqueda que conoces? Cul es el mejor? 2. Cules son los rdenes de las complejidades de cada uno de los mtodos de ordenacin y bsqueda vistos en esta prctica? Cul es el menos complejo?

Karim Guevara, lvaro Fernndez

Sesin 05

Algoritmos y estructura de datos I

Pgina 15

VI BIBLIOGRAFIA Y REFERENCIAS
BIBLIOGRAFA BSICA D.S.Malik, DATA STRUCTURES USIGN C++, Thomson Learning, 2003 J. Galve. ALGORITMIA, Ed.Adisson Wesley, Espaa, 2000. Brassard, ANLISIS DE ALGORITMOS, Ed. Mc. Graw Hill., Espaa, 1999.,

BIBLIOGRAFA COMPLEMENTARIA Wirth M., ALGORITMOS Y ESTRUCTURA DE DATOS, Ed. Addison Wesley, Mxico, 1997 Aho. DISEO Y ANLISIS DE ALGORITMOS, Ed. Addison Wesley. USA, 1999. Deitel & Deitel COMO PROGRAMAR EN C/C++. Editorial Prentice Hall, 1995.

Karim Guevara, lvaro Fernndez

Sesin 05

Você também pode gostar