Problemas al intentar hacer mas eficiente un algoritmo de ordenacion

Iniciado por Dark00, 14 Noviembre 2012, 01:04 AM

0 Miembros y 2 Visitantes están viendo este tema.

Dark00

 Ola, sucede que estoy tratando de que mi algoritmo sea mas eficiente, ya que podria suceder de
que los numeros que el usuario haya ingresado ya estivieran totalmente ordenado o parcialmente
En esta situacion igual se cumplen los dos ciclos, lo cual no es bueno el metodo que utilizo es el
ordenamiento burbuja, alguien tiene alguna idea de como pueda encararlo, aki el codigo :

Código (cpp) [Seleccionar]
#include <iostream>
#define TAM 6

using namespace::std;

int main()
{
   int C[TAM] = {0, 0};
   int temporal;
   
   for( int i=0; i<TAM; i++)
   {    
   cout << "\nIgrese el elemento " << i + 1 << " : " << endl;
   cin >> C[i];
    }
   
   for( int i=0; i<TAM-1; i++)
      for( int j=0; j<=TAM-1; j++)
      {      
         if ( C[j] > C[j + 1] )
         {  
           temporal = C[j];
           C[j] = C[j + 1];
           C[j + 1] = temporal;
         }
      }
   cout << "\nElementos ordenados con el metodo de ordenamiento burbuja\n" << endl;
   
   for( int j=0; j<TAM; j++)
   {
      cout << "\t" << C[j];
    }
   
   return 0;
}


Desde ya gracias

apache_888

El algoritmo de ordenación de la burbuja no es el más eficiente. El mejor sería el Quicksort. De todas formas si quieres usar el de la burbuja se me ocurre una cosa que hará más eficiente tu programa, aunque obviamente se notará en listas grandes...muy grandes.

Veo que el intercambio de las variables lo haces usando una variable temporal, pues se puede hacer sin necesitar esa temporal, y además bastante más rápido, simplemente tienes que trabajar a nivel de bits de la siguiente forma.

Supón que quieres intercambiar X e Y:
   x = x^y;
   y = x^y;
   x = x^y;


La operación ^ es la XOR. Con esto se intercambian las variables mucho antes y sin necesidad de gastar memoria en ninguna variable temporal.

Espero te sirva de algo.

AgnesBlack

hmm yo lo mejoraria de la siguiente manera , te lo escribo en  pseucodigo procedure

1:ingresar I=2 , B=0
2: Mientra(Ciclo Condicionado)I<N Y B=0
2.1. hacer B=1
2.2 Ciclo Incondicionado J:=N paso -1 hasta I
2.2.1 Pregunto a[j]<a[j-1]
2.2.2 Si es si B=0
2.2.3 aux=a[j]
2.2.4 a[j]=a[j-1]
2.2.5 a[j-1]=aux
2.3 salgo del ciclo incondicionado e incremento I=I+1


y otra manera es la tecnica de burbuja de plomo si quieres te paso , ese es el procedimiento , me gusta este metodo ya que es eficiente cuando los vectores tan ordenados

Dark00

apache_888 con el metodo que me proporcionaste mi algoritmo quedaria algo asi no:

Código (cpp) [Seleccionar]
for( int i=0; i<TAM-1; i++)
       for( int j=0; j<=TAM-1; j++)
       {       
          if ( C[j] > C[j + 1] )
          { 
            C[j] ^= C[j + 1];
            C[j + 1] ^= C[j];
            C[j] ^= C[j + 1];
           
          }
       }

Pero segun mi entender el intercambio de valores con una variable temporal, es algo mas rapida
en tiempo de ejecucion, ya que en CPU modernas el metodo XOR es bastante mas lenta respecto a una variable temporal.
AgnesBlack me gustaria ver en que consiste la tecnica de burbuja de plomo me la pasas

Un saludo  ;D

Ferno

En vez de tener 2 ciclos for, podrías reemplazar por dos ciclos while, y tener un flag que te indique si el vector ya está ordenado o no.

Es decir, el code que vos tenés realiza los dos ciclos SIEMPRE, pero si tuvieras un flag que te indique si alguna vez en esos dos ciclos NO entras a hacer el swap (es decir, que el vector ya está ordenado) entonces seteas el flag y al momento de volver al while, sale del loop (no tiene sentido seguir si el vector ya está ordenado).

Espero se haya entendido! (Yo lo conozco como "Burbujeo optimizado" pero desconozco si ese nombre es universal je).

Saludos! Avisame si no entendiste algo!

Dark00

#5
Muchas gracias Ferno gracias a la recomendacion que me diste lo he dejado asi:

Código (cpp) [Seleccionar]
for ( int i=1; ((i<TAM)&&(flag==1)); i++ )
   {  flag = 0;
      for ( int j=0; j<(TAM-i); j++ )
      {      
         if ( C[j] > C[j + 1] )
         {  
           temporal = C[j];
           C[j] = C[j + 1];
           C[j + 1] = temporal;
           flag = 1;
          }
       }
   }


Ferno que opinais al respecto cualquier mejora a esta sera bien recibida, por lo menos evitamos el peor de los casos O(TAM^2) jeje.

Un saludo  ;D

Ferno

#6
Si lo hacés de ese modo, creo que la variable flag tenés que inicializarla en 0 al entrar al primer for (fijate que siempre es 1 en tu caso). Es decir, la condición para que entre al for es que i < TAM y flag == 1. Por ende, entrás al for, inicializás en 0 el flag, entra al segundo ciclo, y si nunca entro al if ( para hacer el swap ) entonces el vector está ordenado, por ende, la variable flag siempre será 0, y así, sale del for. Espero que se entienda!

BTW, creo que al método del burbujeo no hay más que hacerle. Si es por complejidad algorítmica, lo máximo que se le puede hacer es cortar cuando el algoritmo ve que el vector ya está ordenado (es decir, es un algoritmo un poco más inteligente que el burbujeo común).

Para algo más eficiente, hay que buscar otro método de ordenamiento, no se podría estrujar más el burbujeo a mi parecer :P

Dark00

Si efectivamente modificado ando distraido, investigare sobre otros metodos de ordenamiento ya
que este ya no se puede estrujar asi como lo dices jeje

Un saludo amigo  ;D

Ferno

Que bueno que haya servido!

Métodos de ordenamiento hay muchos. Lo interesante es estudiar y entender el orden de cada uno para comparar la eficiencia.
Te recomiendo ver el quicksort.

Saludos!

rir3760

En el caso del método de ordenación BubbleSort puedes utilizar el contador del bucle externo (numero de elementos a ordenar) para indicar el limite superior del bucle interno (ultimo elemento a verificar), mas o menos así:
for (i = N - 1; i > 0; i--){
   intercambio = 0;
   
   for (j = 0; j < i; j++)
      if (elem[j] > elem[j + 1]){
         /* Intercambiar elementos j y j + 1 */
         
         intercambio = 1;
      }
   
   if (!intercambio)
      break;
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language