SlideShare una empresa de Scribd logo
1 de 8
Algoritmos divide y vencerás
Ejemplo 1: elemento mayoritario
Ejemplo 2: algoritmo de ordenación quickSort
Este tipo de algoritmos se usa en la resolución de problemas que pueden ser simplificados
en problemas más sencillos, cuando hablo de simplificación del problema me refiero a
reducir el volumen de datos manejados.
Se pueden distinguir tres partes fundamentales:
1. Los casos base: son las sentencias que se ejecutarán cuando no sea posible reducir
más el problema
2. La simplificación del problema: es un bloque de instrucciones cuya finalidad es dividir
el problema en subproblemas menores del mismo tipo.
3. La parte recursiva: consiste en hacer una llamada a la propia función para que
trabaje sobre los subproblemas obtenidos anteriormente.
Ejemplo 1:
Se quiere encontrar un algoritmo para obtener, si lo hay, el elemento mayoritario de una
colección de números enteros.
Se considera elemento mayoritario a aquel que aparece más de n/2 veces, donde n es la
cantidad de elementos de la colección de datos.
En la imagen se muestra el diagrama de flujo del algoritmo implementado para la resolución
del problema.
A continuación se muestra el código en Java correspondiente a la implementación del
algoritmo.
public class Mayoritario {
/**
* Excepción personalizada que se lanza cuando no hay elemento mayoritario
**/
public static class NoMayoritarioException extends Exception{
public NoMayoritarioException(){
super("No hay elementos mayoritarios");
}
}
/**
* Devuelve un entero correspondiente al elemento mayoritario de un
*ArrayList de enteros.
*¡Ojo porque el contenido del ArrayList se pierde!
* @param cjto Si quiere conservar los datos pase una copia del original
* @return
* @throws mayoritario.Mayoritario.NoMayoritarioException
*/
public int calcMayoritario(ArrayList<Integer> cjto)throws NoMayoritarioException{
//Inicio de los casos base
if(cjto.size()<2){
throw new NoMayoritarioException();
}
switch(cjto.size()){
case 2:
if(cjto.get(0) ==cjto.get(1)) {
return cjto.get(0);
}
throw new NoMayoritarioException();
case 3:
if(cjto.get(0) ==cjto.get(1)||cjto.get(0) ==cjto.get(2)) {
return cjto.get(0);
}else if(cjto.get(2) ==cjto.get(1)){
return cjto.get(1);
}
throw new NoMayoritarioException();
}
if(cjto.size()==2){
}
//Selección de candidatos
ArrayList<Integer> candidatos;
candidatos = new ArrayList<>();
for(int i=0;i<cjto.size()-2;i+=3){
if(cjto.get(i) ==cjto.get(i+1) || cjto.get(i) ==cjto.get(i+2)){
candidatos.add(cjto.get(i));
}if(cjto.get(i+1) ==cjto.get(i+2)){
candidatos.add(cjto.get(i+1));
}
}
int len=cjto.size();
if(len%2==0 && cjto.get(len-2) ==cjto.get(len-1)){
candidatos.add(cjto.get(len-1));
}
//Aplico la recursión
if(candidatos.size()>=cjto.size()/2){
//Alivio un poco la carga espacial, con lo que se pierden los datos de partida
cjto=null;
return this.calcMayoritario(candidatos);
}else{
throw new NoMayoritarioException();
}
}
}
Comparación con otras alternativas
Al aplicar este algoritmo en cada llamada a la función se recorre una sola vez la colección de
datos y de una a otra llamada el número de elementos es como mucho la mitad del
anterior.
Las alternativas más directas para resolver este problema sin usar un algoritmo de este tipo
pasarían por recorrer todos los elementos hasta encontrar uno que se repita más de n/2
veces. El caso más favorable es cuando el primer elemento es el mayoritario por lo que
tendrá complejidad lineal, pero en el resto de casos será cuadrática
Otra opción pasa por ordenar primero la colección, pero habría que tener en cuenta la
complejidad del algoritmo de ordenación.
Otra posibilidad sería utilizar un algoritmo dinámico que se apoyase en una colección de
posibles soluciones, donde cada elemento está compuesto por el valor y el número de
repeticiones. En ese caso se recorrería una sola vez la colección inicial y un máximo de n
veces, en el peor de los casos, la colección auxiliar para comprobar si el valor i-ésimo ya se
encuentra en la colección auxiliar e insertarlo o incrementar el valor de sus repeticiones. Por
lo que tanto la complejidad espacial como temporal serán mayores.
Ejemplo 2: algoritmo quickSort
El algoritmo quickSort es uno de los casos más típicos de aplicación de algoritmos del tipo
divide y vencerás. Consiste en la ordenación de una colección indexada de objetos
dividiendo de forma recursiva la colección en subconjuntos que se caracterizan porque los
elementos del subconjunto anterior aun elemento dado, pivote, son menores que este y los
del subconjunto posterior son mayores. Al hacer subconjuntos de los subconjuntos de forma
recursiva se logra dividir el problema en muchos subproblemas triviales.
Cabe destacar que con este algoritmo no es necesario un paso posterior de mezcla para
obtener la colección ordenada.
La complejidad del algoritmo es cuadrática en el peor de los casos y nLogn en los casos
mejor y medio. El caso será mejor o peor en función de la distancia entre el pivote elegido y
la mediana del conjunto de datos, cuanto más alejado peor. En la implementación que se
muestra a continuación se escoge como pivote al primer elemento del subconjunto, por lo
que este algoritmo es susceptible de ser optimizado sin mucho esfuerzo, aunque hay que
tener en cuenta la complejidad del algoritmo de elección del pivote para estimar la eficiencia
final del nuevo algoritmo.
public static void quickSort(int[] a,int prim, int ult){
if(prim<ult){
//Genero subconjuntos
int l=pivote(a,prim,ult);
//Aplico recursión sobre los subconjuntos
if(l>prim){quickSort(a,prim,l-1);}
if(l<ult){quickSort(a,l+1,ult);}
}//Caso base prim=ult
}
/**
* Devuelve la posición del pivote, elemento que por la izquierda solo
* tiene elementos de valor inferior y por la derecha de valor superior.
* Sobra decir que lo que hace es colocar los elementos a derecha o
* del pivote según su valor.
*/
private static int pivote(int[] a,int prim, int ult){
int i=prim+1;
int l=ult;
while(a[i]<=a[prim] && i<ult){i++;}
while(a[l]>a[prim]){l--;}
while(i<l){
intercambia(a,i,l);
while(a[i]<=a[prim]){i++;}
while(a[l]>a[prim]){l--;}
}
intercambia(a,prim,l);
return l;
}
ALGORITMO POR FUERZA BRUTA
El algoritmo para una búsqueda binaria es método muy útil dentro de un arreglo unidimencional.
Generalmente se le da este nombre búsqueda binaria porque el algoritmo divide en dos el arregelo.
La única condición para que funcióne el algoritmo es que los datos estén ordenados de menor a
mayor.
El metodo mas facil para hacer esto es por la “Fuerza Bruta” Pero este método puede resultar
ineficiente cuando se tiene una gran cantidad de datos, ya que busca posición por posición hasta que
encuentra el dato que se requiere.
El código por fuerza bruta es muy sencillo.
[crayon lang="java"]
for(int i=0; i<Arreglo.length; i++)
if(Arreglo[i] == elemento)
System.out.println(“Elemento encontrado en la posicion: ” + i);
[/crayon]
Se recorre todo el arreglo y se verifica si la posición i es parecida o igual al dato que se busca, el
código anterior se puede mejorar simplemente agregandole una bandera, pero aun asi no es lo
suficientemente bueno.
1. Se declaran los índices superior e inferior. El inferior igual a 0 y el superior con el
tamaño del arreglo menor a 1.
2. Se calcula el centro del arreglo con la siguiente formula:
centro = (superior + inferior) / 2
3. Verificamos si el arreglo en la posición centro es igual al dato que se busca. Si es
igual significa que encontramos el dato y retornamos al centro.
4. Si son diferentes verificamos si el arreglo en la posición centro es mayor al dato que
que queremos buscar. Si es mayor actualizamos superior: superior = centro – 1, si
no actualizamos inferior: inferior = centro + 1.
5. Volvemos al paso 2.
Cuando ya no se cumpla la condicón del ciclo y no se encontro el dato retornamos -1 indicando que
el dato no se encuentra en el arreglo.
Se tiene un arreglo {2, 3, 5, 7, 9, 11, 14, 18, 22, 25} y se quiere buscar el dato 18, entonces el
inferior toma el valor de 0 y superior el valor de 9 (ya que es tamaño del arreglo menos 1).
Calculamos el centro, centro = (superior + inferior) / 2
centro = (9 + 0) / 2
centro = 4
división entera(ignorando el decimal).
Arreglo en la posición centro es 9 (Arreglo[centro] = 9) ya que empieza de 0.
Comprobamos si arreglo en la posición centro es igual al dato que queremos buscar Arreglo[centro] =
dato, como Arreglo[centro] = 9 y dato = 18. no son iguales por lo tanto ahora verificamos si es
mayor, en este caso no lo es entonces actualizamos inferior = centro + 1, esto hace que podamos
descartar todos los datos del centro hacia atras, esto reduce nuestro arreglo a {11, 14, 18, 22, 25}. Y
así seguiremos hasta que Arreglo[centro] = dato.
Como se puede notar este método es bastante eficiente en arreglos grandes, por ejemplo supongamos
que tenemos un arreglo de 10000 datos, y estamos buscando un dato que se encuentra en la posición
6000, solo en la primera vuelta del ciclo ya se pueden descartar los primeros 5000 valores, en cambio
por fuerza bruta se tendrian que realizar esos 6000 ciclos para poder localizar el dato.
[crayon lang="Java"]
public class BusquedaBinaria
{
public static int busquedaBinaria(int[] Arreglo, int elemento)
{
int i = 0, centro = 0, posicion = 0, inferior = 0, superior = Arreglo.length-1;
while(inferior <= superior)
{
centro = (superior + inferior) / 2;
if (Arreglo[centro] == elemento)
return centro;
else
if (Arreglo[centro] > elemento)
superior = centro – 1;
else
inferior = centro + 1;
}
return -1;
}
public static void main (String[] args)
{
java.util.Scanner Leer = new java.util.Scanner(System.in);
System.out.print(“Tamanio del arreglo: “);
int tamanioArreglo = Leer.nextInt();
int[] Arreglo = new int[tamanioArreglo];
for(int i=0; i<Arreglo.length; i++)
Arreglo[i] = Leer.nextInt();
System.out.print(“Elemento a buscar: “);
int elemento = Leer.nextInt();
int posicion = busquedaBinaria(Arreglo, elemento);
if(posicion == -1)
System.out.println(“nElemento no encontrado”);
else
System.out.println(“nElemento ” + elemento + ” encontrado en la posición ” + posicion);
}
}
[/crayon]
Si lo quieren probar directamente descarguen de aquí:

Más contenido relacionado

La actualidad más candente

Administración de transacciones, problemas, candados e interbloqueos
Administración de transacciones, problemas, candados e interbloqueosAdministración de transacciones, problemas, candados e interbloqueos
Administración de transacciones, problemas, candados e interbloqueosjocuva101
 
Funciones de un sistema de proteccion + matrices de acceso
Funciones de un sistema de proteccion + matrices de accesoFunciones de un sistema de proteccion + matrices de acceso
Funciones de un sistema de proteccion + matrices de accesoMarco Lopez
 
Arreglos Unidimensionales - Java - NetBeans
Arreglos Unidimensionales - Java - NetBeansArreglos Unidimensionales - Java - NetBeans
Arreglos Unidimensionales - Java - NetBeansDaniel Gómez
 
Métodos de ordenación externa
Métodos de ordenación externaMétodos de ordenación externa
Métodos de ordenación externaEdwin Narváez
 
Guia 1 de hilos y procesos posix
Guia 1 de hilos y procesos posixGuia 1 de hilos y procesos posix
Guia 1 de hilos y procesos posixMariano Gutierrez
 
Sistema de-maquina-virtual
Sistema de-maquina-virtualSistema de-maquina-virtual
Sistema de-maquina-virtualkerlly villon
 
Factory method
Factory methodFactory method
Factory methodAutentia
 
Organizacion de un sistema operativo
Organizacion de un sistema operativoOrganizacion de un sistema operativo
Organizacion de un sistema operativofulgn
 
Nube: conceptos, usos y aplicaciones
Nube: conceptos, usos y aplicacionesNube: conceptos, usos y aplicaciones
Nube: conceptos, usos y aplicacionesAlfredo Vela Zancada
 
arboles avl con codigo en java
arboles avl con codigo en javaarboles avl con codigo en java
arboles avl con codigo en javamarhoz
 
Patrones de diseño
Patrones de diseñoPatrones de diseño
Patrones de diseñoKelly Cuervo
 
04 Servidores ws2019.ppt
04 Servidores ws2019.ppt04 Servidores ws2019.ppt
04 Servidores ws2019.pptJuanaReategui
 
Unidad 3 topicos avanzados de programacion
Unidad 3 topicos avanzados de programacionUnidad 3 topicos avanzados de programacion
Unidad 3 topicos avanzados de programacionIrving Che
 

La actualidad más candente (20)

Administración de transacciones, problemas, candados e interbloqueos
Administración de transacciones, problemas, candados e interbloqueosAdministración de transacciones, problemas, candados e interbloqueos
Administración de transacciones, problemas, candados e interbloqueos
 
Back Tracking
Back TrackingBack Tracking
Back Tracking
 
Funciones de un sistema de proteccion + matrices de acceso
Funciones de un sistema de proteccion + matrices de accesoFunciones de un sistema de proteccion + matrices de acceso
Funciones de un sistema de proteccion + matrices de acceso
 
Algoritmo de dekker
Algoritmo de dekker Algoritmo de dekker
Algoritmo de dekker
 
Arreglos Unidimensionales - Java - NetBeans
Arreglos Unidimensionales - Java - NetBeansArreglos Unidimensionales - Java - NetBeans
Arreglos Unidimensionales - Java - NetBeans
 
Métodos de ordenación externa
Métodos de ordenación externaMétodos de ordenación externa
Métodos de ordenación externa
 
Guia 1 de hilos y procesos posix
Guia 1 de hilos y procesos posixGuia 1 de hilos y procesos posix
Guia 1 de hilos y procesos posix
 
Sistema de-maquina-virtual
Sistema de-maquina-virtualSistema de-maquina-virtual
Sistema de-maquina-virtual
 
Factory method
Factory methodFactory method
Factory method
 
colecciones en java
colecciones en javacolecciones en java
colecciones en java
 
Organizacion de un sistema operativo
Organizacion de un sistema operativoOrganizacion de un sistema operativo
Organizacion de un sistema operativo
 
Nube: conceptos, usos y aplicaciones
Nube: conceptos, usos y aplicacionesNube: conceptos, usos y aplicaciones
Nube: conceptos, usos y aplicaciones
 
arboles avl con codigo en java
arboles avl con codigo en javaarboles avl con codigo en java
arboles avl con codigo en java
 
Unidad 3 Listas Java
Unidad 3 Listas JavaUnidad 3 Listas Java
Unidad 3 Listas Java
 
Patrones de diseño
Patrones de diseñoPatrones de diseño
Patrones de diseño
 
Diagramas uml
Diagramas umlDiagramas uml
Diagramas uml
 
Unidad 5
Unidad 5Unidad 5
Unidad 5
 
04 Servidores ws2019.ppt
04 Servidores ws2019.ppt04 Servidores ws2019.ppt
04 Servidores ws2019.ppt
 
Bomba Logica
 Bomba Logica Bomba Logica
Bomba Logica
 
Unidad 3 topicos avanzados de programacion
Unidad 3 topicos avanzados de programacionUnidad 3 topicos avanzados de programacion
Unidad 3 topicos avanzados de programacion
 

Similar a Divide y vencerás

3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)luis freddy
 
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dimeluis freddy
 
Ordenar arreglos en java
Ordenar arreglos en javaOrdenar arreglos en java
Ordenar arreglos en javaeccutpl
 
Metodos De Ordenamiento
Metodos De OrdenamientoMetodos De Ordenamiento
Metodos De Ordenamientolichic
 
Diagramas De Flujo
Diagramas De FlujoDiagramas De Flujo
Diagramas De Flujocarlospaul
 
Tiempo de ejecucion de particiones (quicksort)
Tiempo de ejecucion de particiones (quicksort)Tiempo de ejecucion de particiones (quicksort)
Tiempo de ejecucion de particiones (quicksort)Linio Colquehuanca Rodrigo
 
3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetos
3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetos3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetos
3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetosluis freddy
 

Similar a Divide y vencerás (20)

Complejidad Computacional
Complejidad ComputacionalComplejidad Computacional
Complejidad Computacional
 
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime (3)
 
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime
3 desarollo manejo datos capitulo 2 -02 operaciones arreglos dos dime
 
Ordenar arreglos en java
Ordenar arreglos en javaOrdenar arreglos en java
Ordenar arreglos en java
 
Metodos De Ordenamiento
Metodos De OrdenamientoMetodos De Ordenamiento
Metodos De Ordenamiento
 
Informe ordenamiento
Informe ordenamientoInforme ordenamiento
Informe ordenamiento
 
dqwrwer
dqwrwerdqwrwer
dqwrwer
 
Presentacion
PresentacionPresentacion
Presentacion
 
Módulo 2
Módulo 2Módulo 2
Módulo 2
 
Divide y Vencerás
Divide y VencerásDivide y Vencerás
Divide y Vencerás
 
Diagramas De Flujo
Diagramas De FlujoDiagramas De Flujo
Diagramas De Flujo
 
Tiempo de ejecucion de particiones (quicksort)
Tiempo de ejecucion de particiones (quicksort)Tiempo de ejecucion de particiones (quicksort)
Tiempo de ejecucion de particiones (quicksort)
 
Tarea6
Tarea6Tarea6
Tarea6
 
Tarea6
Tarea6Tarea6
Tarea6
 
Diagramas de Secuencia.
Diagramas de Secuencia.Diagramas de Secuencia.
Diagramas de Secuencia.
 
Elemento3
Elemento3Elemento3
Elemento3
 
Elemento3
Elemento3Elemento3
Elemento3
 
Elemento3
Elemento3Elemento3
Elemento3
 
3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetos
3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetos3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetos
3 desarollo manejo datos capitulo 3 -03 aplicaciones arreglo objetos
 
Java básico
Java  básicoJava  básico
Java básico
 

Divide y vencerás

  • 1. Algoritmos divide y vencerás Ejemplo 1: elemento mayoritario Ejemplo 2: algoritmo de ordenación quickSort Este tipo de algoritmos se usa en la resolución de problemas que pueden ser simplificados en problemas más sencillos, cuando hablo de simplificación del problema me refiero a reducir el volumen de datos manejados. Se pueden distinguir tres partes fundamentales: 1. Los casos base: son las sentencias que se ejecutarán cuando no sea posible reducir más el problema 2. La simplificación del problema: es un bloque de instrucciones cuya finalidad es dividir el problema en subproblemas menores del mismo tipo. 3. La parte recursiva: consiste en hacer una llamada a la propia función para que trabaje sobre los subproblemas obtenidos anteriormente. Ejemplo 1: Se quiere encontrar un algoritmo para obtener, si lo hay, el elemento mayoritario de una colección de números enteros. Se considera elemento mayoritario a aquel que aparece más de n/2 veces, donde n es la cantidad de elementos de la colección de datos. En la imagen se muestra el diagrama de flujo del algoritmo implementado para la resolución del problema.
  • 2. A continuación se muestra el código en Java correspondiente a la implementación del algoritmo. public class Mayoritario { /** * Excepción personalizada que se lanza cuando no hay elemento mayoritario **/ public static class NoMayoritarioException extends Exception{ public NoMayoritarioException(){ super("No hay elementos mayoritarios"); } } /** * Devuelve un entero correspondiente al elemento mayoritario de un
  • 3. *ArrayList de enteros. *¡Ojo porque el contenido del ArrayList se pierde! * @param cjto Si quiere conservar los datos pase una copia del original * @return * @throws mayoritario.Mayoritario.NoMayoritarioException */ public int calcMayoritario(ArrayList<Integer> cjto)throws NoMayoritarioException{ //Inicio de los casos base if(cjto.size()<2){ throw new NoMayoritarioException(); } switch(cjto.size()){ case 2: if(cjto.get(0) ==cjto.get(1)) { return cjto.get(0); } throw new NoMayoritarioException(); case 3: if(cjto.get(0) ==cjto.get(1)||cjto.get(0) ==cjto.get(2)) { return cjto.get(0); }else if(cjto.get(2) ==cjto.get(1)){ return cjto.get(1); } throw new NoMayoritarioException(); } if(cjto.size()==2){ } //Selección de candidatos ArrayList<Integer> candidatos; candidatos = new ArrayList<>(); for(int i=0;i<cjto.size()-2;i+=3){ if(cjto.get(i) ==cjto.get(i+1) || cjto.get(i) ==cjto.get(i+2)){ candidatos.add(cjto.get(i)); }if(cjto.get(i+1) ==cjto.get(i+2)){ candidatos.add(cjto.get(i+1)); } } int len=cjto.size(); if(len%2==0 && cjto.get(len-2) ==cjto.get(len-1)){ candidatos.add(cjto.get(len-1)); } //Aplico la recursión if(candidatos.size()>=cjto.size()/2){ //Alivio un poco la carga espacial, con lo que se pierden los datos de partida cjto=null; return this.calcMayoritario(candidatos); }else{ throw new NoMayoritarioException(); } } } Comparación con otras alternativas
  • 4. Al aplicar este algoritmo en cada llamada a la función se recorre una sola vez la colección de datos y de una a otra llamada el número de elementos es como mucho la mitad del anterior. Las alternativas más directas para resolver este problema sin usar un algoritmo de este tipo pasarían por recorrer todos los elementos hasta encontrar uno que se repita más de n/2 veces. El caso más favorable es cuando el primer elemento es el mayoritario por lo que tendrá complejidad lineal, pero en el resto de casos será cuadrática Otra opción pasa por ordenar primero la colección, pero habría que tener en cuenta la complejidad del algoritmo de ordenación. Otra posibilidad sería utilizar un algoritmo dinámico que se apoyase en una colección de posibles soluciones, donde cada elemento está compuesto por el valor y el número de repeticiones. En ese caso se recorrería una sola vez la colección inicial y un máximo de n veces, en el peor de los casos, la colección auxiliar para comprobar si el valor i-ésimo ya se encuentra en la colección auxiliar e insertarlo o incrementar el valor de sus repeticiones. Por lo que tanto la complejidad espacial como temporal serán mayores. Ejemplo 2: algoritmo quickSort El algoritmo quickSort es uno de los casos más típicos de aplicación de algoritmos del tipo divide y vencerás. Consiste en la ordenación de una colección indexada de objetos dividiendo de forma recursiva la colección en subconjuntos que se caracterizan porque los elementos del subconjunto anterior aun elemento dado, pivote, son menores que este y los del subconjunto posterior son mayores. Al hacer subconjuntos de los subconjuntos de forma recursiva se logra dividir el problema en muchos subproblemas triviales. Cabe destacar que con este algoritmo no es necesario un paso posterior de mezcla para obtener la colección ordenada. La complejidad del algoritmo es cuadrática en el peor de los casos y nLogn en los casos mejor y medio. El caso será mejor o peor en función de la distancia entre el pivote elegido y la mediana del conjunto de datos, cuanto más alejado peor. En la implementación que se muestra a continuación se escoge como pivote al primer elemento del subconjunto, por lo que este algoritmo es susceptible de ser optimizado sin mucho esfuerzo, aunque hay que tener en cuenta la complejidad del algoritmo de elección del pivote para estimar la eficiencia
  • 5. final del nuevo algoritmo. public static void quickSort(int[] a,int prim, int ult){ if(prim<ult){ //Genero subconjuntos int l=pivote(a,prim,ult); //Aplico recursión sobre los subconjuntos if(l>prim){quickSort(a,prim,l-1);} if(l<ult){quickSort(a,l+1,ult);} }//Caso base prim=ult } /** * Devuelve la posición del pivote, elemento que por la izquierda solo * tiene elementos de valor inferior y por la derecha de valor superior. * Sobra decir que lo que hace es colocar los elementos a derecha o * del pivote según su valor. */ private static int pivote(int[] a,int prim, int ult){ int i=prim+1; int l=ult;
  • 6. while(a[i]<=a[prim] && i<ult){i++;} while(a[l]>a[prim]){l--;} while(i<l){ intercambia(a,i,l); while(a[i]<=a[prim]){i++;} while(a[l]>a[prim]){l--;} } intercambia(a,prim,l); return l; } ALGORITMO POR FUERZA BRUTA El algoritmo para una búsqueda binaria es método muy útil dentro de un arreglo unidimencional. Generalmente se le da este nombre búsqueda binaria porque el algoritmo divide en dos el arregelo. La única condición para que funcióne el algoritmo es que los datos estén ordenados de menor a mayor. El metodo mas facil para hacer esto es por la “Fuerza Bruta” Pero este método puede resultar ineficiente cuando se tiene una gran cantidad de datos, ya que busca posición por posición hasta que encuentra el dato que se requiere. El código por fuerza bruta es muy sencillo. [crayon lang="java"] for(int i=0; i<Arreglo.length; i++) if(Arreglo[i] == elemento) System.out.println(“Elemento encontrado en la posicion: ” + i); [/crayon] Se recorre todo el arreglo y se verifica si la posición i es parecida o igual al dato que se busca, el código anterior se puede mejorar simplemente agregandole una bandera, pero aun asi no es lo suficientemente bueno. 1. Se declaran los índices superior e inferior. El inferior igual a 0 y el superior con el tamaño del arreglo menor a 1. 2. Se calcula el centro del arreglo con la siguiente formula: centro = (superior + inferior) / 2 3. Verificamos si el arreglo en la posición centro es igual al dato que se busca. Si es igual significa que encontramos el dato y retornamos al centro. 4. Si son diferentes verificamos si el arreglo en la posición centro es mayor al dato que que queremos buscar. Si es mayor actualizamos superior: superior = centro – 1, si no actualizamos inferior: inferior = centro + 1. 5. Volvemos al paso 2. Cuando ya no se cumpla la condicón del ciclo y no se encontro el dato retornamos -1 indicando que el dato no se encuentra en el arreglo.
  • 7. Se tiene un arreglo {2, 3, 5, 7, 9, 11, 14, 18, 22, 25} y se quiere buscar el dato 18, entonces el inferior toma el valor de 0 y superior el valor de 9 (ya que es tamaño del arreglo menos 1). Calculamos el centro, centro = (superior + inferior) / 2 centro = (9 + 0) / 2 centro = 4 división entera(ignorando el decimal). Arreglo en la posición centro es 9 (Arreglo[centro] = 9) ya que empieza de 0. Comprobamos si arreglo en la posición centro es igual al dato que queremos buscar Arreglo[centro] = dato, como Arreglo[centro] = 9 y dato = 18. no son iguales por lo tanto ahora verificamos si es mayor, en este caso no lo es entonces actualizamos inferior = centro + 1, esto hace que podamos descartar todos los datos del centro hacia atras, esto reduce nuestro arreglo a {11, 14, 18, 22, 25}. Y así seguiremos hasta que Arreglo[centro] = dato. Como se puede notar este método es bastante eficiente en arreglos grandes, por ejemplo supongamos que tenemos un arreglo de 10000 datos, y estamos buscando un dato que se encuentra en la posición 6000, solo en la primera vuelta del ciclo ya se pueden descartar los primeros 5000 valores, en cambio por fuerza bruta se tendrian que realizar esos 6000 ciclos para poder localizar el dato. [crayon lang="Java"] public class BusquedaBinaria { public static int busquedaBinaria(int[] Arreglo, int elemento) { int i = 0, centro = 0, posicion = 0, inferior = 0, superior = Arreglo.length-1; while(inferior <= superior) { centro = (superior + inferior) / 2; if (Arreglo[centro] == elemento) return centro; else if (Arreglo[centro] > elemento) superior = centro – 1; else inferior = centro + 1; } return -1; }
  • 8. public static void main (String[] args) { java.util.Scanner Leer = new java.util.Scanner(System.in); System.out.print(“Tamanio del arreglo: “); int tamanioArreglo = Leer.nextInt(); int[] Arreglo = new int[tamanioArreglo]; for(int i=0; i<Arreglo.length; i++) Arreglo[i] = Leer.nextInt(); System.out.print(“Elemento a buscar: “); int elemento = Leer.nextInt(); int posicion = busquedaBinaria(Arreglo, elemento); if(posicion == -1) System.out.println(“nElemento no encontrado”); else System.out.println(“nElemento ” + elemento + ” encontrado en la posición ” + posicion); } } [/crayon] Si lo quieren probar directamente descarguen de aquí: