Siguiendo con los tutoriales sobre el manejo de struct en C, hoy vamos a ver cómo ordenar un arreglo que contiene structs, tomando en cuenta una propiedad del struct para realizar el ordenamiento.

Recuerda que debes tener conocimientos básicos sobre lo que es un struct, un arreglo de structs y los métodos de ordenamiento de arreglos.

Declarando arreglo y temporal

En todos los métodos de ordenación (si no recuerdo mal) se van a realizar intercambios dentro del array, así que necesitamos tener una variable temporal del struct. Por lo tanto comenzamos declarando un struct de ejemplo, así como un temporal y el arreglo:

#define MAXIMA_LONGITUD_CADENA 50
#define CANTIDAD_PERSONAS 2

struct persona
{
    char nombre[MAXIMA_LONGITUD_CADENA];
    int edad;
    double altura;
};

struct persona personas[CANTIDAD_PERSONAS];
struct persona temporal;

El intercambio con memcpy

Vamos a estar trabajando con structs, y no con datos nativos ni con cadenas. Por lo tanto para intercambiar no bastará hacer una asignación usando el signo de =, tenemos que copiar el espacio de memoria.

Para esto nos va a servir la función memcpy que viene dentro de string.h. El intercambio quedaría así:

// Intercambiar
memcpy(&temporal, &personas[indiceActual], sizeof(struct persona));
memcpy(&personas[indiceActual], &personas[indiceSiguienteElemento], sizeof(struct persona));
memcpy(&personas[indiceSiguienteElemento], &temporal, sizeof(struct persona));

De este modo copiamos todo el struct y lo movemos de un lugar a otro.

Ordenando arreglo de structs

Pasemos al punto más importante, que es ordenar el array que contiene datos struct. No cambia nada si lo comparamos con el ordenamiento de un arreglo de otro tipo, solo hay que saber cómo hacer las cosas.

Para este ejemplo voy a usar el método de la burbuja, comparando la altura de las personas del arreglo. De este modo al final tendremos un arreglo ordenado por altura de manera descendente.

El código del método queda así:

void ordenarArreglo()
{
    int x;
    for (x = 0; x < CANTIDAD_PERSONAS; x++)
    {
        int indiceActual;
        for (indiceActual = 0; indiceActual < CANTIDAD_PERSONAS - 1;
             indiceActual++)
        {
            int indiceSiguienteElemento = indiceActual + 1;

            // Ordenar por altura, de manera descendente
            if (personas[indiceActual].altura < personas[indiceSiguienteElemento].altura)
            {
                // Intercambiar
                memcpy(&temporal, &personas[indiceActual], sizeof(struct persona));
                memcpy(&personas[indiceActual], &personas[indiceSiguienteElemento], sizeof(struct persona));
                memcpy(&personas[indiceSiguienteElemento], &temporal, sizeof(struct persona));
            }
        }
    }
}

La comparación la estamos haciendo en la línea 13. Recuerda que justo en esta línea es en donde podrías cambiar el atributo del struct para comparar.

Si fueras a ordenar por nombre, deberías usar strcmp para ordenar un arreglo de cadenas.

Te recuerdo que este método modificará al arreglo de manera interna, y que el arreglo es una variable global, así que no necesitamos recibir parámetros en la función, ni regresar algo.

Poniendo todo junto

Te mostraré cómo usar esta función que te mostré. Repito que puedes usar cualquier método y ordenar con cualquier propiedad del struct. En este caso para la demostración primero imprimí el arreglo sin ordenar, luego lo ordené y finalmente lo imprimí ordenado.

/*
  https://parzibyte.me/blog
*/#include <stdio.h>
#include <string.h> // strncpy
#define MAXIMA_LONGITUD_CADENA 50
#define CANTIDAD_PERSONAS 2

struct persona
{
    char nombre[MAXIMA_LONGITUD_CADENA];
    int edad;
    double altura;
};

struct persona personas[CANTIDAD_PERSONAS];
struct persona temporal;

void ordenarArreglo()
{
    int x;
    for (x = 0; x < CANTIDAD_PERSONAS; x++)
    {
        int indiceActual;
        for (indiceActual = 0; indiceActual < CANTIDAD_PERSONAS - 1;
             indiceActual++)
        {
            int indiceSiguienteElemento = indiceActual + 1;

            // Ordenar por altura, de manera descendente
            if (personas[indiceActual].altura < personas[indiceSiguienteElemento].altura)
            {
                // Intercambiar
                memcpy(&temporal, &personas[indiceActual], sizeof(struct persona));
                memcpy(&personas[indiceActual], &personas[indiceSiguienteElemento], sizeof(struct persona));
                memcpy(&personas[indiceSiguienteElemento], &temporal, sizeof(struct persona));
            }
        }
    }
}
int main(void)
{
    // Asignar datos
    personas[0].altura = 1.2;
    personas[0].edad = 20;
    strncpy(personas[0].nombre, "Luis Cabrera Benito", MAXIMA_LONGITUD_CADENA);

    personas[1].altura = 2.1;
    personas[1].edad = 30;
    strncpy(personas[1].nombre, "Leon Scott Kennedy", MAXIMA_LONGITUD_CADENA);
    // Recorrer antes de ordenar
    printf("Antes de ordenar\n");
    int i;
    for (i = 0; i < CANTIDAD_PERSONAS; i++)
    {
        struct persona personaActual = personas[i];
        printf("Nombre: %s. Edad: %d. Altura: %lf\n", personaActual.nombre, personaActual.edad, personaActual.altura);
    }
    ordenarArreglo();
    // Recorrer después
    printf("Después de ordenar\n");

    for (i = 0; i < CANTIDAD_PERSONAS; i++)
    {
        struct persona personaActual = personas[i];
        printf("Nombre: %s. Edad: %d. Altura: %lf\n", personaActual.nombre, personaActual.edad, personaActual.altura);
    }
    return 0;
}

La salida al ejecutarlo es:

Ordenar arreglo de structs en C – Ejemplo de código y ejecución

Fíjate en que en el primer caso la persona con altura de 1.2 aparece primero, y en el segundo, aparece al final. En este caso el ejemplo fue con 2 elementos, pero podría ser cualquier cantidad y el ordenamiento seguiría funcionando.

Si quieres puedes leer más sobre C en el blog de Parzibyte.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Servidor HTTP en Android con Flutter

El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…

8 horas hace

Imprimir automáticamente todos los PDF de una carpeta

En este post te voy a enseñar a designar una carpeta para imprimir todos los…

1 día hace

Guía para imprimir en plugin versión 1 desde Android

En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…

6 días hace

Añadir tasa de cambio en sistema de información

Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…

2 semanas hace

Comprobar validez de licencia de plugin ESC POS

Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…

2 semanas hace

Imprimir euro € en impresora térmica

Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…

3 semanas hace

Esta web usa cookies.