FUNCIONES DE ORDENACIÓN Y BÚSQUEDA.
Descripcion:
void qsort(void *base,size_t num,size_t tamaño, int(*comparar)(const *void,const *void))
La función qsort() ordena el array al cual apunta (base) utilizando el método de quicksort. Este método se considera en general como el mejor algoritmo de clasificación de propósito general. El numero de elementos que hay en el array esta especificado por (num) y el tamaño (en bytes) de cada elemento es descrito por (tamaño).
La función a la que apunta (comparar) se utiliza para comparar un elemento del array con la (clave). La forma de la función comparar debe ser:
nombre_funcion(const void *arg1,const void *arg2)
Debe proporcionar los valores siguientes:
Si arg1 es menor que arg2, debe proporcionar un valor menor que cero.
Si arg1 es igual que arg2, debe proporcionar un valor cero.
Si arg1 es mayor que arg2, debe proporcionar un valor mayor que cero.
Ejemplo:
#include <stdio.h>
#include <conio.h>
#include <search.h>
int Comparar(const void *,const void *);
int main(void)
{
const
int NUMEL=100;
int Num;
int
Lista[NUMEL];
register
int i,j;
clrscr();
printf("Cuantos numeros seran: ");
scanf("%d",&Num);
printf("\n");
for(i=0;i<Num;i++){
printf("Teclee el valor [%d]=> ",i+1);
scanf("%d",&Lista[i]);
}
qsort(Lista,Num,sizeof(Lista[0]),Comparar);
printf("\n Lista de valores ordenada:\n\n");
for(j=0;j<Num;j++)
printf(" %3d\n",Lista[j]);
getch();
clrscr();
return
0;
}
int Comparar(const void *Elemento1,const void
*Elemento2)
{
if(*(int
*)Elemento1 < *(int *)Elemento2)
return
(-1);
else
if(*(int *)Elemento1 > *(int *)Elemento2)
return
(1);
else
return
(0);
}
Descripcion:
void
*lsearch(const void *clave, const void *base,
unsigned int num, unsigned int
tamaño,
int(*comparar)(const void *, const void*))
La función lsearch() ejecuta una búsqueda lineal de un dato en una array y no necesariamente clasificado. Si el dato no se encuentra la función lsearch() lo añade al final de este.
clave: Es el dato a buscar.
base: Es un puntero al primer elemento del array.
num: Es el numero de elementos del array.
tamaño: Es el tamaño (longitud) en bytes de un elemento.
comparar: Es un puntero a una función definida por el usuario, que compara dos elementos.
La forma de la funcion comparar debe ser:
nombre_funcion(const void *arg1,const void *arg2)
Debe proporcionar los valores siguientes:
!= 0 Si el arg1 y el arg2, son distintos.
= 0 Si arg1 es igual que arg2.
Si la busqueda falla, la funcion lsearch() retorna un puntero al elemento añadido al final del array.
Ejemplo:
#include <stdio.h>
#include <conio.h>
#include <search.h>
#define NUMEL 20
size_t NELEMENTOS;
int MAX;
int Lista[NUMEL];
int Comparar(const int *Elemento1,const int
*Elemento2)
{
return(*Elemento1 - *Elemento2);
}
int AgregarElemento(int *Dato)
{
int
Temporal = NELEMENTOS;
lsearch(Dato, Lista,&NELEMENTOS, sizeof(int),
(int(*)(const void *,const void *))Comparar);
return(NELEMENTOS == Temporal);
}
int main(void)
{
int
Dato;
int i;
clrscr();
printf(" Escriba cuantos elementos seran: ");
scanf("%d",&MAX);
NELEMENTOS=MAX;
for(i=0;i<MAX;i++){
printf(" Escriba el dato [%d] => ",i+1);
scanf("%d",&Lista[i]);
}
printf("\n\n Escriba el numero a buscar-> ");
scanf("%d",&Dato);
if(AgregarElemento(&Dato)){
printf("\n %d esta en la lista de valores.",Dato);
printf("\n\n Lista de valores:\n\n");
for(i=0;i<MAX;i++)
printf(" %3d\n",Lista[i]);
}
else{
Lista[MAX]=Dato;
printf("\n %d ha sido agregado a la lista de valores.",Dato);
printf("\n\n Lista de valores:\n\n");
for(i=0;i<=MAX;i++)
printf(" %3d\n",Lista[i]);
}
getch();
return
0;
}
Descripcion:
void *lfind(const
void *clave,const void *base,
unsigned int num, unsigned int
tamaño,
int(*comparar)(const void *, const void*))
La funcion lfind() ejecuta una búsqueda lineal de un dato en una array y no necesariamente clasificado.
clave: Es el dato a buscar.
base: Es un puntero al primer elemento del array.
num: Es el numero de elementos del array.
tamaño: Es el tamaño (longitud) en bytes de un elemento.
comparar: Es un puntero a una función definida por el usuario, que
compara dos elementos.
La forma de la función comparar debe ser:
nombre_función(const void *arg1,const void *arg2)
Debe proporcionar los valores siguientes:
!= 0 Si el arg1 y el arg2, son distintos.
= 0 Si arg1 es igual que arg2.
Si la búsqueda falla, la función lfind() retorna NULL.
Ejemplo:
#include <stdio.h>
#include <conio.h>
#include <search.h>
#define NUMEL 20
int Comparar(const int *Elemento1,const int
*Elemento2)
{
return(*Elemento1 - *Elemento2);
}
int main(void)
{
int Lista[NUMEL];
int Dato;
size_t NELEMENTOS;
int
MAX;
int *Encontrar,i;
clrscr();
printf(" Escriba cuantos elementos seran: ");
scanf("%d",&MAX);
NELEMENTOS=MAX;
for(i=0;i<MAX;i++){
printf(" Escriba el dato [%d] => ",i+1);
scanf("%d",&Lista[i]);
}
printf("\n\n Escriba el numero a buscar-> ");
scanf("%d",&Dato);
Encontrar=(int *)lfind(&Dato,Lista,&NELEMENTOS,sizeof(int),
(int(*)(const void *,const void *))Comparar);
if(Encontrar) printf("\n %d esta en la lista.\n",Dato);
else printf("\n %d no se encontro en la lista.\n",Dato);
getch();
return
0;
}
Descripcion:
void
*bsearch(const void *clave, const void *base
unsigned num, unsigned tamaño,
int(*comparar)(const void *,const void *))
La funcion bsearch() lleva a cabo una búsqueda binaria en el array ordenado al que apunta (base), y proporciona un puntero del primer miembro que coincida con la clave a la que apunta (clave). El numero de elementos del array esta especificado en (num), y el tamaño (en bytes) de cada elemento lo describe (tamaño).
La función a la que apunta (comparar) se utiliza para comparar con la clave un elemento del array. La forma de la función comparar debe ser:
nombre_funcion(const void *arg1,const void *arg2)
Debe proporcionar los valores siguientes:
Si arg1 es menor que arg2, debe proporcionar un valor menor que cero.
Si arg1 es igual que arg2, debe proporcionar un valor cero.
Si arg1 es mayor que arg2, debe proporcionar un valor mayor que cero.
Ejemplo:
#include <stdio.h>
#include <conio.h>
#include <search.h>
#define NUMEL 20
int Comparar(const int *Elemento1,const int
*Elemento2)
{
return(*Elemento1 - *Elemento2);
}
int main(void)
{
int
Lista[NUMEL];
int
Dato,MAX;
int
*Busca,i;
clrscr();
printf(" Escriba cuantos elementos seran: ");
scanf("%d",&MAX);
for(i=0;i<MAX;i++){
printf(" Escriba el dato [%d] => ",i+1);
scanf("%d",&Lista[i]);
}
printf("\n\n Escriba el numero a buscar-> ");
scanf("%d",&Dato);
Busca=(int
*)bsearch(&Dato,Lista,MAX,sizeof(int),
(int(*)(const void *,const void
*))Comparar);
if(Busca) printf("\n Esta en la lista.\n");
else printf("\n No se encontro en la lista.\n");
getch();
return 0;
}
Método de la Burbuja.
Hay muchas formas de clasificar datos y una de las más conocidas es la clasificación por el método de la de burbuja.
A continuación se muestra su algoritmo correspondiente, para ordenar una lista de menor a mayor, partiendo de que los datos a ordenar están en una lista de n elementos:
1.- Comparamos el primer elemento
con el segundo, el segundo con el tercero, el tercero con el cuarto, etc.
Cuando el resultado de una comparación sea “mayor
que”, se intercambian los valores de los elementos comparados. Con esto
conseguimos llevar el valor mayor a la posición n.
2.- Repetimos el punto 1, ahora
para los n-1 primeros elementos de la lista. Con esto conseguimos, llevar el
valor mayor de éstos a la posición n-1.
3.- Repetimos el punto 1, ahora para los n-2 primeros elementos de la lista y así sucesivamente.
4.- El proceso termina después de repetir el punto 1, n-1 veces, o cuando al finalizar la ejecución del punto 1 no haya habido ningún cambio.
El pseudocódigo para este algoritmo puede ser el siguiente:
<función clasificar (array “a” de “n” elementos)>
[“a” es un array cuyos elementos son a0, a1, ….., an-1 ]
n = n-1
DO WHILE (“a” no esté ordenado y n > 0)
i = 1
DO
WHILE (i < = n)
IF (a[i-1] > a[i] ) THEN
Intercambiar a[i-1] con a[i]
ENDIF
i = i + 1
ENDDO
n = n
– 1
ENDDO
END < clasificar >
Ejemplo:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void BurbujaString();
void Menu();
int main(void)
{
int
opcion;
system("cls");
Menu();
scanf("%d",&opcion);
while(opcion!=2){
switch(opcion){
case 1 : BurbujaString();
break;
default: printf("\n Opcion Invalida.");
getch();
Menu();
}
Menu();
scanf("%d",&opcion);
}
gotoxy(33,15);
printf("Fin de %s",__FILE__);
getch();
return
0;
}
void Menu(void)
{
system("cls");
gotoxy(35,2);
printf(" M E N U");
printf("\n\n OPCIONES:");
printf("\n\n 1) Lee, ordena y despliega cadenas en forma ascendente.");
printf("\n\n 2) Salida");
printf("\n\n Escoja una opcion: ");
}
void BurbujaString(void)
{
int
n,i,j;
char Arreglo[30][25];
system("cls");
printf("\n Programa que lee, ordena y despliega cadenas");
printf("\n\n Cuantas cadenas va a leer: ");
scanf("%d",&n);
for(i=1;i<=n;i++){
printf("\n De la cadena[%d]: ",i);
scanf("%s",&Arreglo[i]);
if(!isalpha(*Arreglo[i])){
printf("\n Fatal Error. Debe ser una cadena.");
getch();
exit(1);
}
}
for(i=1;i<n;i++)
for(j=1;j<n;j++)
if(strcmp
(Arreglo[j], Arreglo[j+1])>0){
strcpy (Arreglo[0],Arreglo[j]);
strcpy (Arreglo[j],Arreglo[j+1]);
strcpy (Arreglo[j+1],Arreglo[0]);
}
printf("\n\n Las cadenas ordenadas son: ");
for(i=1;i<=n;i++)
printf("\n\n %s",Arreglo[i]);
getch();
}
Método Quicksort
El método de ordenación Quicksort, está generalmente considerado como el mejor algoritmo de ordenación disponible actualmente.
El algoritmo correspondiente a este método, es el siguiente:
1. Se selecciona un valor del array. Este valor se puede escoger aleatoriamente o haciendo la media de un pequeño conjunto de valores tomados del array. El valor óptimo sería aquel que esté precisamente en medio del rango de valores (mediana). No obstante, incluso en el peor de los casos, Quicksort funciona correctamente.
2. Se divide el array en dos partes, una con todos los elementos menores que el valor seleccionado y otra con todos los elementos mayores o iguales.
3. Se repiten los puntos 1 y 2 para cada parte restante hasta que el array esté ordenado.
El proceso descrito es esencialmente recursivo.
El pseudocódigo para este algoritmo puede ser el siguiente:
<función Qs (array “a”) >
Se elige un valor x
DO WHILE (“a” no esté ordenado)
[Dividir “a” en dos partes: inf y sup]
inf con los elementos ai < x
sup con los elementos ai >= x
ENDDO
IF
(existe inf) THEN
Qs(inf )
ENDIF
IF
(existe sup) THEN
Qs(sup)
ENDIF
END < Qs >
Ejemplo:
#include <stdio.h>
#include <conio.h>
#include <string.h>
void OrdenaCadena(char Datos[][10],int Izq,int Der);
void QuicksortString(char Datos[][10],int
Elementos);
void main(void)
{
char cadena[10][10];
int MAX,i;
clrscr();
printf("Cuantas cadenas seran: ");
scanf("%d",&MAX);
for(i=0;i<MAX;i++){
printf("Introduzca una cadena: ");
scanf("%s",cadena[i]);
}
QuicksortString(cadena,MAX);
printf("\n La cadena odenada es: ");
for(i=0;i<MAX;i++)
printf("\n %s",cadena[i]);
getch();
}
void QuicksortString(char Datos[][10],int
Elementos)
{
OrdenaCadena(Datos,0,Elementos-1);
}
void OrdenaCadena(char Datos[][10],int Izq,int Der)
{
register int i,j;
char *Mitad;
char Temporal[10];
i=Izq;
j=Der;
Mitad=Datos[(Izq+Der)/2];
do{
while((strcmp(Datos[i],Mitad)<0)
&& (i<Der)) i++;
while((strcmp(Datos[j],Mitad)>0) && (j>Izq)) j--;
if(i<=j){
strcpy(Temporal,Datos[i]);
strcpy(Datos[i],Datos[j]);
strcpy(Datos[j],Temporal);
i++;
j--;
}
}while(i<=j);
if(Izq < j) OrdenaCadena(Datos,Izq,j);
if(i < Der) OrdenaCadena(Datos,i,Der);
}
Búsqueda binaria
Un método eficiente de búsqueda, que puede aplicarse a los arrays clasificados, es la búsqueda binaria. Partiendo de que los elementos del array están almacenados en orden ascendente, la búsqueda binaria consiste en lo siguiente:
Se selecciona el elemento del centro o aproximadamente del centro de array. Si el valor a buscar no coincide con el elemento seleccionado y en mayor que él, se continúa la búsqueda en la segunda mitad del array. Si por el contrario, el valor a buscar es menor que el valor de elemento seleccionado, la búsqueda continúa en la primera mitad del array. En ambos casos, se halla de nuevo el elemento central, correspondiente al nuevo intervalo de búsqueda, repitiéndose el ciclo. El proceso se repite hasta que se encuentra el valor a buscar, o bien hasta que el intervalo de búsqueda sea nulo, lo que querrá decir que el elemento buscado no figura en el array.
El pseudocódigo para este algoritmo puede ser el siguiente:
< función BúsquedaBinaria (array a, valor a buscar) >
DO WHILE (exista un intervalo donde buscar y no encontrado)
x = elemento mitad del intervalo de búsqueda
IF (valor == x ) THEN
encontrado
ELSE IF (valor > x ) THEN
Buscar “x” en la segunda mitad del intervalo de búsqueda
ENDIF
IF (valor < x) THEN
Buscar “x” en la primera mitad del intervalo d búsqueda.
ENDIF
ENDIF
ENDDO
END <BúsquedaBinaria>
Ejemplo:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
typedef enum{FALSE,TRUE}boolean;
int main(void)
{
const
int NUMEL = 50;
int
Arreglo[NUMEL], i, j, Temporal, y=3, Izq, Der;
int
Valor, LimiteSuperior, LimiteInferior, Pivote;
int MAX;
boolean Encontrado;
div_t division;
clrscr();
gotoxy(1,1);
printf("Escriba cuantos numeros seran: ");
scanf("%d",&MAX);
gotoxy(1,2);
printf("Escriba %d numeros.", MAX);
/*Lee los valores*/
for
(i=0; i<MAX; i++) {
gotoxy(1,y++);
printf("%2d:
", i+1);
scanf("%d", &Arreglo[i]);
}
/*
Ordena los valores. Método SHELL.*/
division=div(MAX,2);
Izq=division.quot;
Der=division.quot;
/*ordena
los valores*/
do {
for
(i=0, j=Der; i<Izq, j<MAX; i++, j++) {
if
(Arreglo[i]>Arreglo[j]) {
Temporal=Arreglo[i];
Arreglo[i]=Arreglo[j];
Arreglo[j]=Temporal;
}
}
Izq++;
Der--;
} while(Izq<MAX);
/*Pregunta por el valor a buscar*/
/*muestra los valores*/
gotoxy(25,2);
printf("Numeros ordenados.");
y=3;
for
(i=0; i<MAX; i++) {
gotoxy(30,y++);
printf("%d", Arreglo[i]);
}
gotoxy(25,24);
printf("Valor a buscar ? : ");
scanf("%d", &Valor);
/*busca si algun valor coincide con la lista*/
for (i=0; i<MAX; i++) {
if
(Valor==Arreglo[i]) {
Encontrado=TRUE;
break;
}
}
/*si encontro algun(os) valor(es) lo(s) procesa*/
if (Encontrado) {
textcolor(YELLOW);
gotoxy(55,2);
cprintf("NUMERO ENCONTRADO");
textcolor(7);
LimiteSuperior=MAX;
LimiteInferior=0;
y=3;
for
(i=0; i<MAX; i++) {
if (Valor>Arreglo[i]) { /*si es mayor avanza a la derecha.*/
Pivote=(LimiteSuperior-LimiteInferior)/2;
LimiteSuperior=Pivote;
LimiteInferior=0;
y++;
}
if (Valor<Arreglo[i]) { /*si es menor avanza a la izquierda.*/
Pivote=(LimiteSuperior-LimiteInferior)/2;
LimiteSuperior=MAX;
LimiteInferior=Pivote;
y++;
}
if (Valor==Arreglo[i]) { /*si es igual imprime la posicion.*/
gotoxy(40,y++);
printf("<------------- En la posicion [%d]", i+1);
}
}
}
else
{
textcolor(YELLOW);
gotoxy(55,1);
cprintf("NUMERO
NO ENCONTRADO");
}
getch();
return
0;
}
Para cualquier duda o sugerencia puedes escribirme a mi correo ajuarezoliveros@yahoo.com.mx
Nota.- Todo los programas han sido probados con los compiladores Turbo C++ versión 3.0 y con el compilador Borland C++ versión 3.1.
Si ejecutan estos programas con algún compilador más antiguo que los que mencionamos por ejemplo: como el Turbo C versión 2.01 o Turbo C++ 1.01 deberán cambiar la librería <search.h> por la librería <stdlib.h> para que les funcione correctamente el programa y no les marque algún error.