AprenderC
← Todas las lecciones

El primero de la fila

Para atender por orden de llegada hay que recordar dónde termina la fila.

1Por qué

La pila devuelve al revés, y para muchas cosas eso es justo lo contrario de lo que se quiere. Una fila de impresión, los turnos de un banco, los mensajes por enviar: ahí se atiende por orden de llegada.

Eso es una cola: entra por un lado y sale por el otro. Sacar es fácil, porque el primero de la fila es la cabeza de la lista y eso ya lo sabes hacer. El problema es meter.

Meter al final significa llegar al final, y llegar al final de una lista es recorrerla entera. Con tres elementos da igual; con treinta mil, cada persona que llega cuesta más que la anterior, y una fila de un banco que se pone más lenta cuanta más gente hay es exactamente lo que no se quiere.

La solución es tan simple que parece trampa: recordar dónde está el final. Un puntero al frente para sacar y otro al fondo para meter. Con eso, las dos operaciones cuestan lo mismo siempre, sin importar el largo.

El único cuidado es la fila vacía, donde no hay fondo al que enganchar: ahí el que llega es a la vez el primero y el último.

2Míralo andar

Este programa funciona. Léelo, y después ejecútalo sin cambiar nada.

#include <stdio.h>
#include <stdlib.h>
typedef struct Nodo {
int valor;
struct Nodo *sig;
} Nodo;
void encolar(Nodo **frente, Nodo **fondo, int x)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = x;
n->sig = NULL;
if (*fondo == NULL)
*frente = n;
else
(*fondo)->sig = n;
*fondo = n;
}
int main(void)
{
Nodo *frente = NULL;
Nodo *fondo = NULL;
encolar(&frente, &fondo, 1);
encolar(&frente, &fondo, 2);
encolar(&frente, &fondo, 3);
while (frente != NULL)
{
printf("%d ", frente->valor);
Nodo *s = frente->sig;
free(frente);
frente = s;
}
printf("\n");
return 0;
}

3Ahora tú

A encolar le falta enganchar al final, así que la fila pierde a todos menos al último. Escribe esa línea, para que salga: 1 2 3

#include <stdio.h>
#include <stdlib.h>
typedef struct Nodo {
int valor;
struct Nodo *sig;
} Nodo;
void encolar(Nodo **frente, Nodo **fondo, int x)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = x;
n->sig = NULL;
if (*fondo == NULL)
*frente = n;
else
*fondo = n;
}
int main(void)
{
Nodo *frente = NULL;
Nodo *fondo = NULL;
encolar(&frente, &fondo, 1);
encolar(&frente, &fondo, 2);
encolar(&frente, &fondo, 3);
while (frente != NULL)
{
printf("%d ", frente->valor);
Nodo *s = frente->sig;
free(frente);
frente = s;
}
printf("\n");
return 0;
}

↖︎ Tu línea va aquí: qué hacer cuando la fila NO está vacía y hay un último al que engancharse.

Ejecutar

Lo que dice tu programa

↖︎ Escribe tu parte y dale a Ejecutar

Qué pasó

Aquí te aviso si tu programa hace algo raro.

    4Qué guarda tu programa

    Memoria

    ↖︎ Ejecuta el programa para ver qué pasa por dentro