Implementación de Listas Enlazadas en C para el Cálculo y Ordenamiento de Promedios
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", ¬a1[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", ¬a2[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", ¬a3[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");
}
}