8 - Proyecto final del tutorial

Integraremos Bubble, Insertion y Selection Sort en un solo proyecto para comparar resultados. El menú permite elegir el algoritmo, ordenar arrays de prueba, medir tiempos y observar el antes y después.

8.1 Implementar Bubble, Insertion y Selection en archivos separados

Mantén cada algoritmo en su propio archivo (bubble_sort.c, insertion_sort.c, selection_sort.c) con sus prototipos en cabeceras o declarados en main.c. Reutiliza swap y imprimir_array para no duplicar código.

Un menú simple por consola es suficiente: lee la opción del usuario (b, i, s) y llama al algoritmo correspondiente. Evita repetir código usando una función que reciba un puntero a función de ordenamiento.

8.3 Ordenar arrays de prueba

Usa varios conjuntos: aleatorio, casi ordenado e inverso. Copia el array original antes de ordenar para poder comparar resultados sin perder los datos iniciales.

8.4 Comparar tiempos de ejecución

Para entradas pequeñas, clock() es suficiente. Si necesitas más precisión, usa cronómetros del sistema u otras utilidades, pero recuerda que los algoritmos son O(n^2) y en listas grandes el tiempo crecerá rápido.

8.5 Imprimir resultados antes y después

Con imprimir_array muestra el estado inicial y el final. En arrays grandes, imprime solo los primeros y últimos elementos o la longitud para no saturar la salida.

8.6 Probar en CLion paso a paso

Coloca breakpoints en los bucles internos para seguir las comparaciones y swaps. Ejecuta el menú varias veces con diferentes entradas para verificar que cada algoritmo produce el mismo resultado ordenado.

8.7 Comparar resultados con arrays de distintos tamaños

Corre el programa con n=10, n=100 y n=500 para ver cómo crecen los tiempos. Anota comparaciones y swaps si quieres construir una tabla similar a la del tema 6.

8.8 Códigos completos del proyecto

Estructura propuesta para un proyecto en CLion. Usa la configuración de ejecución del IDE para compilar todos los archivos juntos y lanzar el programa desde la misma interfaz.

/* swap.h */
void swap(int *a, int *b);
/* swap.c */
#include "swap.h"

void swap(int *a, int *b) {
  int temp = *a;
  *a = *b;
  *b = temp;
}
/* utils.h */
void imprimir_array(const int *arr, int n);
void copiar_array(const int *origen, int *destino, int n);
void llenar_aleatorio(int *arr, int n, int max_val);
/* utils.c */
#include <stdio.h>
#include <stdlib.h>
#include "utils.h"

void imprimir_array(const int *arr, int n) {
  printf("[");
  for (int i = 0; i < n; i++) {
    printf("%d", arr[i]);
    if (i + 1 < n) {
      printf(", ");
    }
  }
  printf("]\n");
}

void copiar_array(const int *origen, int *destino, int n) {
  for (int i = 0; i < n; i++) {
    destino[i] = origen[i];
  }
}

void llenar_aleatorio(int *arr, int n, int max_val) {
  for (int i = 0; i < n; i++) {
    arr[i] = rand() % max_val;
  }
}
/* bubble_sort.c */
#include "swap.h"

void bubble_sort(int *arr, int n) {
  for (int i = 0; i < n - 1; i++) {
    int hubo_intercambio = 0;
    int limite = n - 1 - i;
    for (int j = 0; j < limite; j++) {
      if (arr[j] > arr[j + 1]) {
        swap(&arr[j], &arr[j + 1]);
        hubo_intercambio = 1;
      }
    }
    if (!hubo_intercambio) {
      break;
    }
  }
}
/* insertion_sort.c */
void insertion_sort(int *arr, int n) {
  for (int i = 1; i < n; i++) {
    int actual = arr[i];
    int j = i - 1;
    while (j >= 0 && arr[j] > actual) {
      arr[j + 1] = arr[j];
      j--;
    }
    arr[j + 1] = actual;
  }
}
/* selection_sort.c */
#include "swap.h"

void selection_sort(int *arr, int n) {
  for (int i = 0; i < n - 1; i++) {
    int indice_min = i;
    for (int j = i + 1; j < n; j++) {
      if (arr[j] < arr[indice_min]) {
        indice_min = j;
      }
    }
    if (indice_min != i) {
      swap(&arr[i], &arr[indice_min]);
    }
  }
}
/* main.c */
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "swap.h"
#include "utils.h"

void bubble_sort(int *arr, int n);
void insertion_sort(int *arr, int n);
void selection_sort(int *arr, int n);

typedef void (*sort_fn)(int *, int);

void ejecutar(const char *nombre, sort_fn fn, int *arr, int n) {
  clock_t inicio = clock();
  fn(arr, n);
  clock_t fin = clock();
  double ms = (double)(fin - inicio) * 1000.0 / CLOCKS_PER_SEC;
  printf("%s -> tiempo: %.3f ms\n", nombre, ms);
}

int main(void) {
  const int MAX = 10000;
  int original[MAX];
  int trabajo[MAX];
  int n = 0;

  srand((unsigned)time(NULL));

  printf("Ingrese cantidad de elementos (max %d): ", MAX);
  if (scanf("%d", &n) != 1 || n <= 0 || n > MAX) {
    printf("Tamano no valido.\n");
    return 1;
  }

  llenar_aleatorio(original, n, 1000);
  printf("Antes: ");
  imprimir_array(original, n);

  printf("Seleccione algoritmo (b)ubble, (i)nsertion, (s)election: ");
  char opcion = 0;
  if (scanf(" %c", &opcion) != 1) {
    printf("Entrada no valida.\n");
    return 1;
  }

  copiar_array(original, trabajo, n);
  switch (opcion) {
    case 'b':
      ejecutar("Bubble Sort", bubble_sort, trabajo, n);
      break;
    case 'i':
      ejecutar("Insertion Sort", insertion_sort, trabajo, n);
      break;
    case 's':
      ejecutar("Selection Sort", selection_sort, trabajo, n);
      break;
    default:
      printf("Opcion no reconocida.\n");
      return 1;
  }

  printf("Despues: ");
  imprimir_array(trabajo, n);
  return 0;
}