Implementación de Listas Enlazadas en C para el Cálculo y Ordenamiento de Promedios

Informática8,39 KB

Introducción al Programa de Promedios con Listas Enlazadas

El siguiente programa implementado en lenguaje C permite calcular los promedios de notas escolares de varios alumnos y almacenarlos dinámicamente mediante listas simplemente enlazadas. El usuario puede seleccionar el orden de visualización de los resultados mediante un menú interactivo en consola:

  • Orden original: inserción al final de la lista.
  • Descendente: de mayor promedio a menor promedio.
  • Ascendente: de menor promedio a mayor promedio.
  • Inverso: inserción al principio de la lista (último ingresado al primero).

Librerías Requeridas y Estructuras de Datos

El sistema requiere de las cabeceras estándar de C para la entrada/salida de datos, gestión de memoria y operaciones de consola:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

Se define el tipo de dato tipoNodo, que contiene el valor del promedio y un puntero hacia el nodo siguiente:

typedef struct dos {
    float promedio;
    struct dos *siguiente;
} tipoNodo;

typedef tipoNodo *pNodo;
typedef tipoNodo *Lista;

Prototipos de Funciones

A continuación se declaran las operaciones esenciales para manipular las listas enlazadas:

void insertarPrincipio(Lista *lista, float promedio);
void insertarFinal(Lista *lista, float promedio);
void insertarMenor(Lista *lista, float promedio);
void insertarMayor(Lista *lista, float promedio);
int listaVacia(Lista lista);
void mostrar(Lista lista);

Función Principal (main)

La función main despliega el menú de opciones, valida la entrada del usuario, solicita el RUT y las tres notas correspondientes por estudiante (en una escala de 10 a 70), calcula el promedio y lo inserta en la lista según la opción seleccionada.

int main() {
    printf("\n\t\t\tBIENVENIDOS:");
    printf("\n\n\t\t CALCULA TUS PROMEDIOS");
    getche();
    system("cls");
    fflush(stdin);

    int opcion;
    printf("\n\t\t\t\tMENU:");
    printf("\n\n\t1- MOSTRAR PROMEDIOS EN EL MISMO ORDEN INGRESADO");
    printf("\n\n\t2- MOSTRAR PROMEDIOS DESDE EL MAYOR HASTA EL MENOR");
    printf("\n\n\t3- MOSTRAR PROMEDIOS DESDE EL MENOR HASTA EL MAYOR");
    printf("\n\n\t4- MOSTRAR PROMEDIOS DEL ULTIMO INGRESADO HASTA EL PRIMERO");

    do {
        printf("\n\n\tDIGITE LA OPCION DESEADA:");
        scanf("%d", &opcion);
        fflush(stdin);
        if (opcion < 1 || opcion > 4) {
            printf("\n\nERROR EN EL INGRESO,");
            printf("\nDEBE INGRESAR UNA OPCION DE 1 A 4,");
            printf("\nINTENTE NUEVAMENTE...");
        }
    } while (opcion < 1 || opcion > 4);

    Lista listaPrincipio = NULL;
    Lista listaFinal = NULL;
    Lista listaMenor = NULL;
    Lista listaMayor = NULL;

    char rut[4][12];
    float nota1[4];
    float nota2[4];
    float nota3[4];
    float pro[4];

    for (int i = 0; i < 4; i++) {
        system("cls");
        fflush(stdin);
        printf("\n\n\tALUMNO NUMERO %d :", i + 1);

        printf("\n\n\tINGRESE RUT: ");
        gets(rut[i]);
        fflush(stdin);

        do {
            printf("\n\nINGRESE LA NOTA NUMERO 1:");
            scanf("%f", &nota1[i]);
            fflush(stdin);
            if (nota1[i] < 10 || nota1[i] > 70) {
                printf("\n\nERROR! LA NOTA DEBE SER MAYOR A 10 Y MENOR A 70,");
                printf("\nINTENTE NUEVAMENTE...");
            }
        } while (nota1[i] < 10 || nota1[i] > 70);

        do {
            printf("\n\nINGRESE LA NOTA NUMERO 2:");
            scanf("%f", &nota2[i]);
            fflush(stdin);
            if (nota2[i] < 10 || nota2[i] > 70) {
                printf("\n\nERROR! LA NOTA DEBE SER MAYOR A 10 Y MENOR A 70,");
                printf("\nINTENTE NUEVAMENTE...");
            }
        } while (nota2[i] < 10 || nota2[i] > 70);

        do {
            printf("\n\nINGRESE LA NOTA NUMERO 3:");
            scanf("%f", &nota3[i]);
            fflush(stdin);
            if (nota3[i] < 10 || nota3[i] > 70) {
                printf("\n\nERROR! LA NOTA DEBE SER MAYOR A 10 Y MENOR A 70,");
                printf("\nINTENTE NUEVAMENTE...");
            }
        } while (nota3[i] < 10 || nota3[i] > 70);

        pro[i] = ((nota1[i] + nota2[i] + nota3[i]) / 3);

        if (opcion == 1) {
            insertarFinal(&listaFinal, pro[i]);
        }
        if (opcion == 2) {
            insertarMenor(&listaMenor, pro[i]);
        }
        if (opcion == 3) {
            insertarMayor(&listaMayor, pro[i]);
        }
        if (opcion == 4) {
            insertarPrincipio(&listaPrincipio, pro[i]);
        }

        printf("\n\nPROMEDIO CALCULADO, PRESIONE ENTER PARA CONTINUAR...");
        getche();
    }

    if (opcion == 1) {
        mostrar(listaFinal);
    }
    if (opcion == 2) {
        mostrar(listaMenor);
    }
    if (opcion == 3) {
        mostrar(listaMayor);
    }
    if (opcion == 4) {
        mostrar(listaPrincipio);
    }

    getche();
    return 0;
}

Implementación de las Operaciones sobre la Lista

1. Inserción al Principio

Inserta un elemento como el nuevo primer nodo de la lista enlazada:

void insertarPrincipio(Lista *lista, float p) {
    pNodo nuevo;
    nuevo = (pNodo)malloc(sizeof(tipoNodo));
    nuevo->promedio = p;
    nuevo->siguiente = *lista;
    *lista = nuevo;
}

2. Inserción al Final

Recorre la lista hasta el último elemento e inserta el nuevo nodo a continuación:

void insertarFinal(Lista *lista, float p) {
    pNodo nuevo, ultimo;
    nuevo = (pNodo)malloc(sizeof(tipoNodo));
    nuevo->promedio = p;

    if (listaVacia(*lista)) {
        nuevo->siguiente = NULL;
        *lista = nuevo;
    } else {
        ultimo = *lista;
        while (ultimo->siguiente) {
            ultimo = ultimo->siguiente;
        }
        nuevo->siguiente = NULL;
        ultimo->siguiente = nuevo;
    }
}

3. Inserción Ordenada de Menor a Mayor

Mantiene los nodos ordenados de forma ascendente según el promedio:

void insertarMayor(Lista *lista, float p) {
    pNodo nuevo, anterior;
    nuevo = (pNodo)malloc(sizeof(tipoNodo));
    nuevo->promedio = p;

    if (listaVacia(*lista) || (*lista)->promedio > p) {
        nuevo->siguiente = *lista;
        *lista = nuevo;
    } else {
        anterior = *lista;
        while (anterior->siguiente && anterior->siguiente->promedio <= p) {
            anterior = anterior->siguiente;
        }
        nuevo->siguiente = anterior->siguiente;
        anterior->siguiente = nuevo;
    }
}

4. Inserción Ordenada de Mayor a Menor

Mantiene los nodos ordenados de forma descendente:

void insertarMenor(Lista *lista, float p) {
    pNodo nuevo, anterior;
    nuevo = (pNodo)malloc(sizeof(tipoNodo));
    nuevo->promedio = p;

    if (listaVacia(*lista) || (*lista)->promedio < p) {
        nuevo->siguiente = *lista;
        *lista = nuevo;
    } else {
        anterior = *lista;
        while (anterior->siguiente && anterior->siguiente->promedio >= p) {
            anterior = anterior->siguiente;
        }
        nuevo->siguiente = anterior->siguiente;
        anterior->siguiente = nuevo;
    }
}

5. Funciones de Verificación y Despliegue

Verifica si la lista apunta a NULL y despliega los elementos en pantalla:

int listaVacia(Lista lista) {
    return (lista == NULL);
}

void mostrar(Lista lista) {
    pNodo nodo = lista;
    fflush(stdin);
    system("cls");

    if (listaVacia(lista)) {
        printf("ERROR! LA LISTA SE ENCUENTRA VACIA...\n");
        getche();
    } else {
        fflush(stdin);
        system("cls");
        printf("\n\nA CONTINUACION SE IMPRIMIRAN LOS PROMEDIOS DE LA LISTA...\n\n");
        fflush(stdin);
        getche();
        system("cls");
        fflush(stdin);

        while (nodo) {
            printf(" %.2f -> ", nodo->promedio);
            nodo = nodo->siguiente;
        }
        printf("NULL\n");
    }
}

Descargar

PDF Word HTML