Professional Documents
Culture Documents
Ordenamiento y Bsqueda
Ms. Ing. CARLOS AURELIO ROMERO SHOLLANDE caromerosh@yahoo.es
UNIVERSIDAD NACIONAL DE TRUJILLO Trujillo - Per
Introduccin
Con frecuencia el programador trabajar con grandes cantidades de informacin almacenada en arreglos. Muchas veces, se requiere ordenar dicha informacin y buscar s un valor especificado esta contenido en algn arreglo.
El ordenamiento, la bsqueda y la mezcla de datos son problemas que estudiaremos en la presente sesin.
Ordenamiento
El ordenamiento de datos (sort en ingls) consiste en colocar los datos en algn orden particular (por ejemplo; ascendente o descendente).
Es una de las tareas que consume ms tiempo; por este motivo, se han desarrollado cientos de mtodos diferentes para la ordenacin de datos, y es imposible determinar cul es el mejor en todas las circunstancias.
Mtodos de Ordenamiento
Los mtodos ms usados son:
Mtodo de la burbuja, es el mtodo ms comn, pero tiene pocas caractersticas positivas y es mejor no utilizarlo. Mtodo de seleccin Mtodo de insercin, son tiles para arreglos pequeos. Mtodo de Shell, es el mtodo que ms se utiliza, incluso para arreglos con miles de entradas.
X[3] t
Es decir: t = X[j] Enseguida se hace una copia del valor del segundo elemento del par (X[j+1]) sobre el primer elemento (X[j]):
Variable auxiliar
Es decir: X[j] = X[j+1] Luego se hace una copia del valor de la variable auxiliar (t) sobre el segundo elemento (X[j+1]):
X[j] X[j+1] Variable auxiliar X[2] X[3] t 5 5 8
Es decir: X[j+1] = t
Un valor grande puede moverse hacia abajo del arreglo muchas posiciones con un solo pase, pero un valor pequeo se mover hacia arriba una sola posicin. En el primer pase, se garantiza que el mayor valor se hunde hasta el fondo del arreglo. En el segundo pase se garantiza que el segundo valor mayor se hunde hasta la penltima posicin y as sucesivamente.
Por lo tanto, los rangos de cada subndice estarn definidos por: i: 1 .. n-1 j: i+1 .. n
Es decir: t = X[i]
Es decir: X[i] = X[j] Finalmente, se copia el valor de la variable auxiliar (t) sobre el segundo elemento X[j]:
X[i] X[j] Variable auxiliar X[2] X[3] t 5 5 8
Variable auxiliar
Ordenamiento Shell
Es un mtodo de ordenamiento muy rpido, fue desarrollado por Donald Shell (1959), el procedimiento es sencillo y corto, pero su comprensin no lo es y se basa en una sucesin de clasificaciones. Es una mejora del mtodo de insercin directa basada en la disminucin de los incrementos o saltos. Se comparan los elementos dos a dos: X[i] con X[i+n/2] y se les ordena. Se hacen las mismas comparaciones pero de la forma: X[i] con X[i+n/2] y se les ordena. Luego se hacen las mismas comparaciones pero de la forma: X[i] con X[i+n/4] y tambin se les ordena. Este proceso contina hasta que se obtiene la clasificacin final. El procedimiento es:
Ordenamiento Shell
1) Se selecciona el salto o intervalo en el arreglo original (k=n/2), se forman grupos de dos elementos cada uno (posiciones [j] y [j+k]) y se clasifica cada grupo por separado (compara parejas de elementos, si no estn ordenados se intercambian de posiciones entre s). Se realiza una o ms repasadas en esta operacin hasta comprobar que ya no se requiere intercambios de posiciones.
Ordenamiento Shell
2) Se selecciona un nuevo salto para el arreglo obtenido en el paso anterior (k=k/2), se forman grupos de dos elementos cada uno y se clasifica cada grupo por separado. Se realiza una o ms repasadas hasta comprobar que ya no se requieren intercambios de posiciones. 3) El procedimiento se repite hasta que el salto sea k=1. Completndose el ordenamiento con las repasadas necesarias hasta comprobar que ya no se requieren intercambios de posiciones.
Ejemplo 1
Ingresar el tamao de un vector as como cada uno de sus elementos. Ordenar los elementos del vector en forma ascendente usando el mtodo 1 de la burbuja. Codificacin:
#include <iostream.h> // ORDENAMIENTO POR BURBUJA 1 #include <conio.h> main() { int n; // Nmero de elementos del vector int i; // Contador que al inicio indica elementos no ordenados int j; // Contador que compara e intercambia elementos int t; // Variable auxiliar usada para el intercambio de valores int x[20]; // Elemento del vector clrscr(); cout<<"Tamao del vector"; cin>>n;
Ejemplo 1
cout<<"Elementos del vector"; for(i=1;i<=n;i++) // Ingreso de datos del vector cout<<"Elemento N "<<i<<" : "; cin>>*(x+i); for(i=1;i<=n;i++) { // Ordenamiento del vector for(j=1;j<=n-1;j++) { if(*(x+j)>*(x+(j+1))) { // Intercambio de valores t=*(x+j); *(x+j)=*(x+(j+1)); *(x+(j+1))=t; } } } clrscr(); cout<<"Vector Ordenado\n\n"; for(i=1;i<=n;i++) cout<<*(x+i)<<endl; } getch(); }
Bsqueda
La bsqueda (search en ingls) es un proceso que permite determinar si un arreglo contiene un valor que sea igual a cierto valor clave. Existen dos tcnicas de bsqueda: Bsqueda lineal Bsqueda binaria
Bsqueda Lineal
La bsqueda lineal es la tcnica ms simple y funciona bien con arreglos pequeos y no ordenados. Consiste en comparar la clave de bsqueda con todos los elementos del arreglo. Por ejemplo, buscar el valor clave = 5 en el arreglo: X[i] = [8 3 5 7].
Clave 3 i 1 2 3 n=4 X[i] 8 3 5 7
Bsqueda Lineal
El procedimiento es el siguiente: 1) Inicialmente a la posicin del elemento buscado (p) se le asigna un valor que no corresponde a ningn valor posible del subndice del arreglo, tal como, -1. p = -1 2) Se genera un bucle que permita comparar la clave con cada uno de los elementos del arreglo: Para i=1 Hasta n Variacin 1 Hacer Si clave = X[1] Entonces p = i
Bsqueda Lineal
3) Si el resultado de la comparacin es verdadera para un valor del subndice del arreglo, entonces este valor ser la posicin del elemento buscado; en el ejemplo, p=3. 4) En el caso de que el valor inicial de p no vari, despus de haberse realizado todas las comparaciones, implica que el valor buscado no existe en el arreglo.
Bsqueda Binaria
La bsqueda binaria es la tcnica de ms alta velocidad y funciona eficientemente con arreglos grandes y ordenados previamente. Consiste en eliminar, tras cada comparacin, la mitad de los elementos del arreglo en los que se efecta la bsqueda. Primero localiza el elemento central del arreglo y luego lo compara con la clave de bsqueda. Si son iguales, se ha encontrado dicha clave y se devuelve el subndice de ese elemento. De otro modo, el problema se reduce a buscar en una mitad del arreglo.
Ejemplo 2
Ingresar el tamao de un vector y cada uno de sus elementos. As mismo, ingresar un nmero y en el caso de que ste se encuentre dentro del vector, reportar la posicin que ocupa. En caso contrario, reportar el mensaje: El elemento buscado no ha sido encontrado. Usar el mtodo de bsqueda lineal. Codificacin:
#include <iostream.h> // BUSQUEDA LINEAL #include <conio.h> main() { int n; // Nmero de elementos del vector int i; // Contador de los elementos del vector int clave; // Valor que ser buscado en el arreglo int p; // Posicin del elemento buscado
Ejemplo 2
int x[20]; // Elementos del vector clrscr(); cout<<"Tamao del vector"; cin>>n; cout<<"Elementos del vector"; for(i=1;i<=n;i++) { // Ingreso de elementos del vector cout<<"Elemento N "<<i<<" : "; cin>>*(x+i); } clrscr(); // Introduccin de clave de bsqueda cout<<"Ingrese el nmero a buscar: "; cin>>clave; p=-1; // Ubicacin de la posicin del nmero buscado for(i=1;i<=n;i++) if(*(x+i)==clave) p = i; if(p!=-1) cout<<"Elemento buscado se encuentra en la posicin: "<<p; else cout<<"El elemento buscado no ha sido encontrado"; getch(); }
Mezcla
La mezcla o fusin (merge en ingls) consiste en tomar dos arreglos (X[i] e Y[j]) ordenados previamente y obtener un nuevo arreglo (Z[h]) tambin ordenado a partir de la intercalacin de ambos. El algoritmo ms sencillo para resolver el problema consiste en: Situar todos los elementos de X en el nuevo vector Z. Situar todos los elementos Y en el nuevo vector Z. Ordenar todo el vector Z. Evidentemente esta es una solucin correcta.
Mezcla
Sin embargo se ignora por completo el hecho de que los arreglos X e Y estn clasificados, lo que supondr una ralentizacin (reunin) del proceso en el tiempo. El proceso correcto consiste en lo siguiente: 1) Inicializar los subndices de los tres arreglos X, Y e Z, es decir: i=1, j=1 y h=1 respectivamente. 2) Siempre que los subndices de los dos arreglos iniciales X e Y (es decir, i y j respectivamente), sean menores que sus tamaos (M y N), comparar los elementos respectivos de ambos arreglos y seleccionar el elemento que tiene el menor valor.
Mezcla
1 3 i=4 i=3 i=2 i=1 X[i]<Y[j] j=6 j=5 j=4 j=3 j=2 j=1 2 7 3 4 X[i]
13 17
Y[j]
h=10 h=9 h=8 h=7 h=6 h=5 h=4 h=3 h=2 h=1
10
Mezcla
3) Ubicar el elemento seleccionado en el paso anterior en el nuevo arreglo Z y el subndice del arreglo seleccionado (i j) incrementar en 1. 4) Incrementar el subndice de arreglo resultante h en 1. 5) Seguir esta secuencia de comparaciones hasta que los elementos de uno de los arreglos se haya agotado, es decir, hasta que el valor del subndice de dicho arreglo sea mayor que su tamao. 6) Copiar el resto de elementos del arreglo no agotado en el arreglo resultante Z, sin olvidar que el subndice del arreglo resultante (h) se deber continuar incrementando en 1; hasta obtener, finalmente, su tamao de M + N elementos.
Problema 3
Ingresa dos vectores, ordenarlos en forma descendente, luego obtener y reportar un nuevo vector formado por la mezcla o fusin (merge) de los dos anteriores, tambin ordenado en forma decreciente. Codificacin:
#include <iostream.h> // MEZCLA DE VECTORES #include <conio.h> #define lim 20 main() { int a, b; // Tamao de lo vectores int i, j; // Subndices de los vectores int h, k; // Subndices auxiliares de los vectores int g; // Subndice del vector mezcla int r, t; // Variables para intercambios en ordenamiento int p; // Subndice para el resto del vector no agotado
Problema 3
int x[lim]; // Elementos del primer vector int y[lim]; // Elementos del segundo vector int z[lim]; // Elementos del vector mezcla do { clrscr(); cout<<"Tamao del primer vector :"; cin>>a; cout<<"Tamao del segundo vector :"; cin>>b; } while(a<=0 && b<=0); clrscr(); cout<<"\n\nINGRESO DE DATOS DE PRIMER VECTOR\n\n"; for(i=1;i<=a;i++) { cout<<i; cin>>*(x+i); } clrscr();
Problema 3
cout<<"\n\nINGRESO DATOS DE SEGUNDO VECTOR\n\n"; for(j=1;j<=b;j++) { cout<<j; cin>>*(y+j); } for(i=1;i<=a-1;i++) { // Ordenamiento del primer vector for(h=i+1;h<=a;h++) { if(*(x+i)>*(x+h)) { r=*(x+i); *(x+i)=*(x+h); *(x+h)=r; } } } for(j=1;j<=b-1;j++) { // Ordenamiento del segundo vector for(k=j+1;k<=b;k++) { if(*(y+j)>*(y+k)) { t = *(y+j); *(y+j) = *(y+k); *(y+k) = t; } } }
Problema 3
i=1; // Valor inicial del subndice del primer vector j=1; // Valor inicial del subndice del segundo vector g=1; // Valor inicial del subndice del vector mezcla while(i<=a && j<=b) { // Mezclar los vectores if(*(x+i)<=*(y+j)) { // Ingreso de elementos de primer vector *(z+g)=*(x+i); i=i+1; } else { // Ingreso de elementos del segundo vector *(z+g)=*(y+j); j=j+1; } g=g+1; // Incremento del subndice del vector mezcla } // Los elementos de algn arreglo pudiera no haberse agotado // Para superar el problema, se copia el resto del vector no agotado
Problema 3
if(i>a) { // Si ndice 1er. vector llega a ser mayor que su tamao for(p=j; p<=b; p++) { *(z+g)=*(y+p); g=g+1; } } else { // Si ndice de 2do. vector llega a ser mayor que su tamao for(p=i; p<=a; p++) { *(z+g)=*(x+p); g=g+1; } } clrscr(); cout<<"\n\nDATOS DEL VECTOR MEZCLADO\n\n"; cout<<"Nmero Dato"; for(g=1;g<=a+b;g++) { // Vector mezcla cout<<g<< <<*(z+g); } getch(); }