Comportamiento erróneo algoritmo quicksort

Hola

Tengo un problema con el algoritmo de quick sort. Resulta que al asignar el pivote de distintas maneras obtengo una versión de quick sort que ordena correctamente y otra que no. A qué es debido esto?
Aquí el main:

#include <stdio.h>
#include <stdlib.h>

#define LON 20

void quick_sort(int *vector, int izq, int der);

main()
{
srand(time(NULL));
int vector[LON], indice;
for(indice=0;indice<LON;indice++)
  vector[indice]=(int)(((((double)rand())/((double)RAND_MAX))*200)+1);
  quick_sort(vector,0,LON-1);
for(indice=0;indice<LON;indice++)
  printf("%d \n", vector[indice]);
return 0;
}


Aqui el quick sort bueno:
void quick_sort(int *vector, int left, int right)
{
int aux, izq, der;
int central=vector[(left+right)/2];     /*----------------------------------------AQUÍ--------------------------------------*/
izq=left;
der=right;
do
{
  while(vector[izq]<central) izq++;
 
  while(vector[der]>central) der--;

  if(izq<der){
  aux=vector[izq];
  vector[izq]=vector[der];
  vector[der]=aux;
  izq++;
  der--;
  }
  else if(izq==der) izq++;
}while(izq<=der);
if(der>left) quick_sort(vector, left, der);
if(izq<right) quick_sort(vector, izq,right);
}


Aquí el quick sort malo:
void quick_sort(int *vector, int left, int right)
{
int aux, izq, der;
int central=(left+right)/2;  /*----------------------------------------AQUÍ--------------------------------------*/
izq=left;
der=right;
do
{
  while(vector[izq]<vector[central]) izq++;   
 
  while(vector[der]>vector[central]) der--;

  if(izq<der){
  aux=vector[izq];
  vector[izq]=vector[der];
  vector[der]=aux;
  izq++;
  der--;
  }
  else if(izq==der) izq++;
}while(izq<=der);
if(der>left) quick_sort(vector, left, der);
if(izq<right) quick_sort(vector, izq,right);
}


Gracias de antemano.
(mensaje borrado)
El pivote tiene que pertenecer al conjunto que está siendo ordenado. La versión 'malo' no lo asegura.
Hola ferdy:

No me queda muy claro lo que me comentas. He comprobado el valor de la variable indice central y es en ambos igual, excepto que por alguna extraña razón al pasar los dos while su valor se modifica en el quicksort malo.
Buenas,

fíjate en el 2º algoritmo, aunque no cambies el valor de central, el vector lo modificas, por lo que se puede dar el caso que el valor de vector[central] cambie, ya que los componentes del vector han cambiado.

Saludos.
Mirad, si yo compilo este código, puedo ver que el indice del pivote es modificado siquiera no se realice ningún movimiento de los elementos del array. Es más, ni siquiera se llama a sí misma ni una sola vez y la variable es modificada, por qué? no lo sé....
#include <stdio.h>
#include <stdlib.h>

#define LON 20

void quick_sort(int *vector, int izq, int der);
void quick_sort_malo(int *vector, int left, int right);

main()
{
srand(time(NULL));
int vector[LON], indice;
for(indice=0;indice<LON;indice++)
  vector[indice]=(int)(((((double)rand())/((double)RAND_MAX))*200)+1);
  quick_sort(vector,0,LON-1);
  quick_sort_malo(vector,0,LON-1);
for(indice=0;indice<LON;indice++)
  printf("%d \n", vector[indice]);
return 0;
}


void quick_sort_malo(int *vector, int left, int right)
{
int aux, izq, der;
int central=(left+right)/2;    
izq=left;
der=right;
do
{
  while(vector[izq]<vector[central])
  {
   printf("\nVector[central] malo ---> %d", vector[central]);
   izq++;
  }
  printf("\n[central] malo ---> %d", central);
  return;

  while(vector[der]>vector[central]) der--;

  if(izq<der){
   aux=vector[izq];
   vector[izq]=vector[der];
   vector[der]=aux;
   izq++;
   der--;
  }
  else if(izq==der) izq++;
}while(izq<=der);
if(der>left) quick_sort_malo(vector, left, der);
if(izq<right) quick_sort_malo(vector, izq,right);
}



void quick_sort(int *vector, int left, int right)
{
int aux, izq, der;
int central=vector[(left+right)/2];
izq=left;
der=right;
do
{
  while(vector[izq]<central)
  {
   printf("\nVector[central] bueno ---> %d", central);
   izq++;
  }
  printf("\n[central] bueno ---> %d", (left+right)/2);
  return;

  while(vector[der]>central) der--;

  if(izq<der){
   aux=vector[izq];
   vector[izq]=vector[der];
   vector[der]=aux;
   izq++;
   der--;
  }
  else if(izq==der) izq++;
}while(izq<=der);
if(der>left) quick_sort(vector, left, der);
if(izq<right) quick_sort(vector, izq,right);
}

Si miras ese código funciona perfectamente, y veras que el índice del pivote no es modificado, otra cosa es que no lo sepas interpretar,
[central] bueno ---> 9
[central] malo ---> 976
160
34
125
21
186
199
174
101
40
36
108
188
145
56
52
161
191
159
17


Si ves esta salida, y piensas que central[bueno]!=central[malo], es simplemente porque te has olvidado un salto de linea en el código, por lo que central[malo] es 9, y no 976

Y como ya te dije en el anterior post, el fallo es el que comentado antes.

Saludos.
Tenéis toda la razón, no sé como no lo vi.

Gracias.
7 respuestas