Laboratorio de algoritmos en C
Métodos de Ordenamiento
Acerca de esta estructura
Visualizador didáctico de algoritmos de ordenamiento sobre arreglos.
1 Preparar y controlar ejecución
Define el arreglo y el método. Ejecutar operación muestra el resultado final; Paso a paso permite preparar el recorrido y avanzar por sus instrucciones.
Paso: 0/0
2 Visualizar y ejecutar
Preparación
Qué cambia y por qué
Prepara la operación para ver sus variables y punteros.
- Aún no hay instrucciones ejecutadas.
Leyenda: C comparación · I intercambio · P pivote · ✓ confirmado · A auxiliar
Código C: Intercambio directo
/**
* @brief Verifica si un arreglo puede procesarse.
*
* @param arreglo Arreglo de enteros.
* @param n Número de elementos del arreglo.
* @return 1 exclusivamente si arreglo != NULL y n > 0; 0 de otro modo.
* @note No inspecciona elementos ni valida longitud real, alineacion, punteros colgantes o tamano de reservas.
*/
static int arreglo_valido(const int arreglo[], size_t n) {
return arreglo != NULL && n > 0;
}
/**
* @brief Intercambia el contenido de dos variables enteras.
*
* @param a Puntero al primer entero.
* @param b Puntero al segundo entero.
* @note NULL a o b se ignora. Con ambos validos son ints escribibles; mismo entero permitido sin cambio. No reserva/libera.
*/
static void intercambiar(int *a, int *b) {
int temporal;
if (a == NULL || b == NULL) return;
temporal = *a;
*a = *b;
*b = temporal;
}
/**
* @brief Ordena un arreglo usando el método de intercambio directo.
*
* @param arreglo Arreglo de enteros a ordenar.
* @param n Número de elementos del arreglo.
* @note Tiempo O(n^2), memoria O(1); no estable por intercambios no adyacentes.
* @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado.
*/
void ordenar_intercambio(int arreglo[], size_t n) {
size_t i, j;
if (!arreglo_valido(arreglo, n)) return;
for (i = 0; i + 1 < n; ++i)
for (j = i + 1; j < n; ++j)
if (arreglo[i] > arreglo[j]) intercambiar(&arreglo[i], &arreglo[j]);
}4 Comprender el método Estrategia, regla que se mantiene y detalles C opcionales
Variables C
Sin inicializar significa declarada, pero todavía sin un valor asignado. No equivale a cero ni indica por sí solo un error.
| Nombre | Tipo | Valor | Significado |
|---|---|---|---|
| Primero crea un arreglo, activa Paso a paso y pulsa Preparar recorrido. | |||
Pila de llamadas
- Sin llamadas activas.
Ciclo actual
Punteros y auxiliares
Estrategia del método
Este estado complementa la explicación junto al gráfico. Los nombres entre paréntesis corresponden al código C.
Regla que se mantiene en este paso
Se mostrará al preparar la ejecución.
Métricas observadas
Perfil teórico
5 Resultados de ejecución Consola C, historial, TAD y exportaciones
Consola C (printf)
Historial de ejecución
Estructura del TAD
#define ORDENAMIENTO_OK 1 #define ORDENAMIENTO_ERROR 0 void imprimir_arreglo(const int arreglo[], size_t n); /** * @brief Copia los elementos de un arreglo origen hacia un arreglo destino. * * @param destino Arreglo destino. * @param origen Arreglo origen. * @param n Número de elementos a copiar. * @return ORDENAMIENTO_OK si la copia fue correcta; ORDENAMIENTO_ERROR en caso contrario. * @pre Buffers vivos de al menos n ints, destino escribible y origen legible, sin solapamiento; n*sizeof(int) representable en size_t. * @note NULL buffers o n==0 retorna ORDENAMIENTO_ERROR sin copiar. Usa memcpy, no memmove; no admite buffers solapados ni valida longitud. No reserva/libera. */ int copiar_arreglo(int destino[], const int origen[], size_t n); /** * @brief Ordena un arreglo usando el método de intercambio directo. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @note Tiempo O(n^2), memoria O(1); no estable por intercambios no adyacentes. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ void ordenar_intercambio(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando selección directa. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @note Tiempo O(n^2), memoria O(1); no estable por intercambio con el minimo distante. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ void ordenar_seleccion(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando inserción directa. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @note Mejor O(n), peor O(n^2), memoria O(1); estable por desplazar solo valores estrictamente mayores. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ void ordenar_insercion(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando burbuja mejorada. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @note Mejor O(n), peor O(n^2), memoria O(1); estable por intercambiar vecinos solo si son estrictamente mayores. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ void ordenar_burbuja(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando Shell Sort. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @note Gaps n/2, n/4, ...; peor O(n^2), memoria O(1); no estable. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ void ordenar_shell(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando QuickSort. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @note Promedio O(n log n), peor O(n^2); pila O(log n) promedio, O(n) peor; no estable. n debe permitir indices int y suma de extremos int. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ void ordenar_quicksort(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando MergeSort. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @return ORDENAMIENTO_OK si se ordenó correctamente; ORDENAMIENTO_ERROR ante arreglo NULL, n == 0 o fallo de memoria. * @note Tiempo O(n log n), auxiliar O(n), pila O(log n); estable porque la mezcla toma primero el lado izquierdo en igualdad. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ int ordenar_mergesort(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando HeapSort. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @note Tiempo O(n log n), sin arreglo auxiliar; heapify recursivo usa pila O(log n), no espacio total O(1); no estable. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ void ordenar_heapsort(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando Counting Sort. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @return ORDENAMIENTO_OK si se ordenó correctamente; ORDENAMIENTO_ERROR ante arreglo NULL, n == 0, rango mayor que ORDENAMIENTO_RANGO_MAX, tamaño no representable o fallo de memoria. * @note Tiempo O(n+k), memoria O(k), k=max-min+1 <= ORDENAMIENTO_RANGO_MAX; reconstruye enteros por frecuencia, sin preservar identidad de registros iguales. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ int ordenar_counting_sort(int arreglo[], size_t n); /** * @brief Ordena delegando en Counting Sort; conserva sus límites de rango y códigos de error. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @return ORDENAMIENTO_OK si se ordenó correctamente; ORDENAMIENTO_ERROR ante arreglo NULL, n == 0, rango mayor que ORDENAMIENTO_RANGO_MAX, tamaño no representable o fallo de memoria. * @note Delegacion exacta a Counting Sort: O(n+k) tiempo, O(k) memoria y mismo limite; no es una implementacion independiente de buckets. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ int ordenar_binsort(int arreglo[], size_t n); /** * @brief Ordena un arreglo usando Radix Sort LSD en base 10. * * Esta implementación acepta enteros negativos separándolos de los no negativos, * ordenando magnitudes y recombinando al final. * * @param arreglo Arreglo de enteros a ordenar. * @param n Número de elementos del arreglo. * @return ORDENAMIENTO_OK si se ordenó correctamente; ORDENAMIENTO_ERROR ante arreglo NULL, n == 0 o fallo de memoria. * @note Base 10, O(d(n+10)) tiempo y O(n+10) memoria. Conteo por digito estable; la inversion final del grupo negativo no garantiza estabilidad de registros negativos iguales. INT_MIN usa magnitud uint32_t y recomposicion protegida. * @note Arreglo NULL o n==0 no se procesa; funciones int retornan ERROR y funciones void no comunican estado. */ int ordenar_radixsort(int arreglo[], size_t n); /** * @brief Ejecuta y muestra un algoritmo de ordenamiento sobre una copia del arreglo base. * * @param nombre Nombre descriptivo del algoritmo. * @param ordenar Función de ordenamiento que no retorna estado. * @param base Arreglo base. * @param n Número de elementos. * @pre nombre es cadena viva terminada en NUL; base contiene n ints legibles, n*sizeof(int) representable. Callback valido recibe copia prestada, no la libera ni retiene; se cumplen sus limites particulares. * @note NULL nombre/callback/base o n==0 no hace nada. Malloc fallido imprime error. Copia base, ejecuta callback, imprime copia y la libera; base queda intacta bajo precondiciones. */ void probar_algoritmo_void(const char *nombre, void (*ordenar)(int[], size_t), const int base[], size_t n); /** * @brief Ejecuta y muestra un algoritmo de ordenamiento que retorna estado. * * @param nombre Nombre descriptivo del algoritmo. * @param ordenar Función de ordenamiento que retorna ORDENAMIENTO_OK o ORDENAMIENTO_ERROR. * @param base Arreglo base. * @param n Número de elementos. * @pre nombre es cadena viva terminada en NUL; base contiene n ints legibles, n*sizeof(int) representable. Callback valido recibe copia prestada, no la libera ni retiene; se cumplen sus limites particulares. * @note NULL nombre/callback/base o n==0 no hace nada. Error de malloc imprime diagnostico; callback con retorno cero imprime error y libera copia sin imprimir arreglo. Exito no cero imprime copia y la libera. */ void probar_algoritmo_int(const char *nombre, int (*ordenar)(int[], size_t), const int base[], size_t n);