Estructuras de Datosc++structtipos personalizadosestructuras

Struct (Estructuras Personalizadas)

Aprende a crear tus propios tipos de datos con struct en C++

OOI Oaxaca9 de febrero de 20265 min read

¿Para qué sirve un struct?

Imagina que estás organizando una competencia y necesitas guardar información de cada participante: su nombre, su puntaje y su escuela. Podrías usar tres arreglos separados:

string nombres[100];
int puntajes[100];
string escuelas[100];

Pero esto es confuso y propenso a errores. ¿Qué pasa si ordenas los puntajes pero olvidas mover los nombres? Se desincroniza todo.

Un struct te permite agrupar datos relacionados en un solo paquete:

struct Participante {
    string nombre;
    int puntaje;
    string escuela;
};

Ahora cada participante es un solo objeto con toda su información junta. Si mueves al participante, toda su información viaja con él.

Definir y usar un struct

#include <iostream>
#include <string>
using namespace std;

// Definición del struct (fuera de main, como un molde)
struct Punto {
    int x;
    int y;
};

int main() {
    // Crear variables de tipo Punto
    Punto a;
    a.x = 3;
    a.y = 5;

    // Otra forma de inicializar
    Punto b = {7, 2};

    // Acceder a los campos con el punto (.)
    cout << "Punto A: (" << a.x << ", " << a.y << ")" << endl;
    cout << "Punto B: (" << b.x << ", " << b.y << ")" << endl;

    return 0;
}

El punto (.) es como abrir la caja y sacar lo que hay dentro.

Vectores de structs

Aquí es donde los structs brillan:

struct Estudiante {
    string nombre;
    int calificacion;
};

int main() {
    int n;
    cin >> n;

    vector<Estudiante> estudiantes(n);

    for (int i = 0; i < n; i++) {
        cin >> estudiantes[i].nombre >> estudiantes[i].calificacion;
    }

    // Encontrar al mejor estudiante
    int mejorIdx = 0;
    for (int i = 1; i < n; i++) {
        if (estudiantes[i].calificacion > estudiantes[mejorIdx].calificacion) {
            mejorIdx = i;
        }
    }

    cout << "Mejor estudiante: " << estudiantes[mejorIdx].nombre
         << " con " << estudiantes[mejorIdx].calificacion << " puntos" << endl;

    return 0;
}

Ordenar structs

Una de las aplicaciones más poderosas: ordenar por cualquier criterio.

Con función de comparación

struct Persona {
    string nombre;
    int edad;
};

bool compararPorEdad(Persona a, Persona b) {
    return a.edad < b.edad;  // Orden ascendente por edad
}

int main() {
    vector<Persona> personas = {
        {"Ana", 25},
        {"Carlos", 18},
        {"María", 30}
    };

    sort(personas.begin(), personas.end(), compararPorEdad);

    for (auto &p : personas) {
        cout << p.nombre << " (" << p.edad << ")" << endl;
    }
    // Carlos (18)
    // Ana (25)
    // María (30)
}

Criterios múltiples

Ordenar por puntaje (descendente), y si empatan, por nombre (alfabético):

bool comparar(Participante a, Participante b) {
    if (a.puntaje != b.puntaje) {
        return a.puntaje > b.puntaje;  // Mayor puntaje primero
    }
    return a.nombre < b.nombre;  // Si empatan, orden alfabético
}

Con operador < (sobrecargar)

Puedes definir cómo se compara tu struct directamente:

struct Evento {
    int inicio;
    int fin;

    bool operator<(const Evento &otro) const {
        return fin < otro.fin;  // Ordenar por tiempo de fin
    }
};

// Ahora puedes usar sort sin función extra
vector<Evento> eventos;
sort(eventos.begin(), eventos.end());

Structs en competencias

Representar aristas de un grafo

struct Arista {
    int origen, destino, peso;

    bool operator<(const Arista &otra) const {
        return peso < otra.peso;
    }
};

vector<Arista> aristas;
aristas.push_back({1, 2, 5});
aristas.push_back({2, 3, 3});
sort(aristas.begin(), aristas.end());  // Ordena por peso

Representar coordenadas

struct Punto {
    double x, y;

    double distancia(Punto otro) {
        double dx = x - otro.x;
        double dy = y - otro.y;
        return sqrt(dx * dx + dy * dy);
    }
};

Punto a = {0, 0};
Punto b = {3, 4};
cout << a.distancia(b) << endl;  // 5

Pair: el struct de dos elementos incorporado

C++ tiene un struct genérico de dos elementos llamado pair:

pair<int, int> p = {3, 5};
cout << p.first << " " << p.second << endl;  // 3 5

// Muy útil para coordenadas
vector<pair<int, int>> puntos;
puntos.push_back({1, 2});
puntos.push_back({3, 4});

// Se ordena automáticamente: primero por first, luego por second
sort(puntos.begin(), puntos.end());
💡

pair es muy cómodo, pero para más de dos campos, usa un struct con nombres descriptivos. Es más legible evento.inicio que evento.first.

Ejercicio de práctica

Lee N estudiantes con nombre y calificación. Ordénalos por calificación descendente y muestra la tabla de posiciones.

Entrada:

4
Ana 85
Carlos 92
María 78
Pedro 92

Salida:

1. Carlos 92
2. Pedro 92
3. Ana 85
4. Maria 78
Ver solución
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Estudiante {
    string nombre;
    int calificacion;
};

bool comparar(Estudiante a, Estudiante b) {
    if (a.calificacion != b.calificacion)
        return a.calificacion > b.calificacion;
    return a.nombre < b.nombre;
}

int main() {
    int n;
    cin >> n;

    vector<Estudiante> est(n);
    for (int i = 0; i < n; i++) {
        cin >> est[i].nombre >> est[i].calificacion;
    }

    sort(est.begin(), est.end(), comparar);

    for (int i = 0; i < n; i++) {
        cout << i + 1 << ". " << est[i].nombre
             << " " << est[i].calificacion << endl;
    }

    return 0;
}

Siguiente paso

Con las estructuras de datos básicas dominadas, avanza a los Algoritmos de Ordenamiento para aprender cómo organizar datos de forma eficiente.