Más punteros...

Iniciado por Bob1098, 16 Septiembre 2014, 16:36 PM

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

Bob1098

Sigo con el tema de los punteros y sigo sin entender que falla ahora.
Tengo el siguiente ejercicio:

"3.Implementar en una función el siguiente algoritmo para ordenar un array de enteros.
La idea es recorrer simultáneamente el array desde el principio y desde el final, comparando los elementos. Si los valores comparados no están en el orden adecuado, se intercambian y se vuelve a empezar el bucle. Si están bien ordenados, se compara el siguiente par.
El proceso termina cuando los punteros se cruzan, ya que eso indica que hemos comparado la primera mitad con la segunda y todos los elementos estaban en el orden correcto.
Usar una función con tres parámetros:
void Ordenar(int* vector, int nElementos, bool ascendente);
De nuevo, no se deben usar enteros, sólo punteros y aritmética de punteros."

El problema esta en que los elementos no parecen intercambiarse ni ordenarse, e incluso algunos toman el valor del estilo de -88483432.

Este es mi código:

Código (cpp) [Seleccionar]

#include <iostream>

using namespace std;

void Ordenar(int*, int, bool);

int main() {
int lista[10] = { 1, 4, 2, 5, 3, 7, 6, 9, 8, 10 };

for (int i = 0; i <= 9; i++) {
cout << lista[i] << " ";
}
cout << endl;
Ordenar(lista, 10, 0);
for (int i = 0; i <= 9; i++) {
cout << lista[i] << " ";
}

cin.sync();
cin.get();
return 0;
}

void Ordenar(int *vector, int nElementos, bool ascendente) {
int *q, *p;

p = vector;
q = &vector[nElementos];
if (ascendente) {
while (p <= q) {
if (*p > *q) {
*p += *q;
*q = *p - *q;
*p -= *q;
}
p++; q--;
}
}
else {
while (p <= q) {
if (*p < *q) {
*p += *q;
*q = *p - *q;
*p -= *q;
}
p++; q--;
}
}
}

rir3760

El error principal se encuentra en la función "Ordenar", el valor inicial del puntero al ultimo elemento es:
Código (cpp) [Seleccionar]
q = &vector[nElementos];
Con eso el puntero "q" apunta a una posición después del ultimo elemento, hay que cambiarlo a:
Código (cpp) [Seleccionar]
q = vector + nElementos - 1;

Y el intercambio hay que cambiarlo ya que ignora ciertos detallitos como que sucede si la suma desborda al tipo int (no recuerdo exactamente si es "implementation defined" o "undefined behavior"). Mejor por sencillo:
Código (cpp) [Seleccionar]
if (*p > *q){
   int aux;
   
   aux = *p;
   *p = *q;
   *q = aux;
}
p++;
q--;


Por ultimo la condición del bucle debe ser "p < q" ya que no tiene sentido el intercambio si los punteros apuntan al mismo elemento.

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

eferion

Código (cpp) [Seleccionar]

void Ordenar(int*, int, bool);

// ...

Ordenar(lista, 10, 0);


Los valores válidos para los booleanos son "true" y "false", acostúmbrate a usar esos valores en vez de 1 y 0.

Código (cpp) [Seleccionar]
Ordenar(lista, 10, false);

aunque también te puedes plantear el uso de enums:

Código (cpp) [Seleccionar]

enum TipoOrden
{
  Ascendente,
  Descendente
};

void Ordenar(int *, int , TipoOrden );

int main( )
{
  // ...
  Ordenar( lista, 10, Ascendente );
  // ...
}

void Ordenar(int *vector, int nElementos, TipoOrden tipoOrden )
{
  // ...

  if ( tipoOrden == Ascendente )
  {
  // ...

Bob1098

#3
Vale, ya mas o menos voy entendiendo la función de los punteros. En cuanto a la propuesta de usar valores true o false para los booleanos, es cierto que leí que es mejor usarlos si se tiene oportunidad. También me parece correcto usar un enum, aunque me parece mucha mas simple una variable bool.

*Aún así, sigo sin conseguir el resultado deseado. No parece que el vector se modifique mucho. El resultado en orden ascendente no cambia, y en orden ascendente se queda así: 10  8  9  6  7  3  5  2  4  1.

Gracias una vez más por las respuestas, gracias a este foro se puede aprender y preguntar dudas =).

Un saludo.

eferion

Cita de: Bob1098 en 16 Septiembre 2014, 22:35 PM
*Aún así, sigo sin conseguir el resultado deseado. No parece que el vector se modifique mucho. El resultado en orden ascendente no cambia, y en orden ascendente se queda así: 10  8  9  6  7  3  5  2  4  1.

Eso es porque tu algoritmo de ordenación no funciona.

Te lo pongo con un ejemplo práctico... si tu tienes: 1  4  2  5  3  7  6  9  8  10.

Incialmente comparas 1 y 10... orden correcto, después comparas 4 y 8... orden correcto, después comparas 2 y 9... nuevamente orden correcto... al final no has cambiado ningún valor de posición.

Lo que te están pidiendo es que implementes el algoritmo de la burbuja, el de toda la vida. La "novedad" que plantea tu ejercicio es que tiene que poderse elegir si empiezan por el principio del array o por el final... pero no te están pidiendo que pongas un puntero al principio, otro al final y que vayas comparándolos entre ellos.

No se si me explico.

Bob1098

Cita de: eferion en 17 Septiembre 2014, 11:57 AM
Eso es porque tu algoritmo de ordenación no funciona.

Te lo pongo con un ejemplo práctico... si tu tienes: 1  4  2  5  3  7  6  9  8  10.

Incialmente comparas 1 y 10... orden correcto, después comparas 4 y 8... orden correcto, después comparas 2 y 9... nuevamente orden correcto... al final no has cambiado ningún valor de posición.

Lo que te están pidiendo es que implementes el algoritmo de la burbuja, el de toda la vida. La "novedad" que plantea tu ejercicio es que tiene que poderse elegir si empiezan por el principio del array o por el final... pero no te están pidiendo que pongas un puntero al principio, otro al final y que vayas comparándolos entre ellos.

No se si me explico.

Entiendo a lo que te refieres, ya he usado ese algoritmo más de una vez, solo que ahora supongo que si estamos tratando el tema de los punteros pretenden que use punteros en lugar de enteros.

Gracias por la respuesta.