Introducción a la estructuras de datos

Introducción a Listas Enlazadas
Definición
Las listas enlazadas son estructuras de datos semejantes a los array salvo que el
acceso a un elemento no se hace mediante un índice sino mediante un puntero.
La asignación de memoria es hecha durante la ejecución. En una lista los
elementos son contiguos en lo que concierne al enlazado.

Construcción del modelo de un elemento de la lista
Para establecer un elemento de la lista, será utilizado el tipo struct. El elemento de
la lista tendrá un campo dato y un puntero siguiente. El puntero siguiente tiene que
ser del mismo tipo que el elemento, si no, no podrá apuntar hacia el elemento. El
puntero siguiente permitirá el acceso al próximo elemento
typedef struct ElementoLista {
char
*dato;
struct ElementoLista *siguiente
}Elemento;

1

Para tener el control de la lista es preferible guardar determinados elementos: el
primer elemento, el último elemento, el número de elementos. Para ello será
empleado otra estructura (no es obligatorio, pueden ser utilizadas variables).
typedef struct ListaIdentificar {
Elemento *inicio;
Elemento *fin;
int tamaño;
}Lista;

Operaciones sobre las listas enlazadas
Para la inserción y la eliminación, una única función bastará si está bien concebida
de acuerdo a lo que se necesite. Debo recordar que este artículo es puramente
didáctico. Por lo tanto, he escrito una función para cada operación de inserción y
eliminación.

Inicialización
void inicializacion (Lista *lista);
Modelo de la función:
void inicializacion (Lista *lista){
lista->inicio = NULL; lista->fin = NULL; tamaño = 0;}
Inserción de un elemento en la lista
Inserción y el registro de los elementos: declaración del elemento que se va a
insertar, asignación de la memoria para el nuevo elemento, llena el contenido del
campo de datos, actualización de los punteros hacia el primer y último elemento si
es necesario. Caso particular: en una lista con un único elemento, el primero es al
mismo tiempo el último. Actualizar el tamaño de la lista Para añadir un elemento a
la lista se presentan varios casos: la inserción en una lista vacía, la inserción al
inicio de la lista, la inserción al final de la lista y la inserción en otra parte de la
lista.

2

Inserción en una lista vacía
Ejemplo de la función:
int ins_en_lista_vacia (Lista *lista, char *dato);

La función retorna 1 en caso de error, si no devuelve 0.
Las etapas son asignar memoria para el nuevo elemento, completa el campo de
datos de ese nuevo elemento, el puntero siguiente de este nuevo elemento
apuntará hacia NULL (ya que la inserción es realizada en una lista vacía, se utiliza
la dirección del puntero inicio que vale NULL), los punteros inicio y fin apuntaran
hacia el nuevo elemento y el tamaño es actualizado.

3

char *dato). char *dato){ Element *nuevo_elemento. Etapas: asignar memoria al nuevo elemento. el tamaño es incrementado 4 . el puntero fin no cambia. rellenar el campo de datos de este nuevo elemento. nuevo_elemento->siguiente = NULL. dato). } Inserción al inicio de la lista Ejemplo de la función: int ins_inicio_lista (Lista *lista. de lo contrario da 0. el puntero siguiente del nuevo elemento apunta hacia el primer elemento. return 0.La función: /* inserción en una lista vacía */ int ins_en_lista_vacia (Lista * lista. if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1. el puntero inicio apunta al nuevo elemento. La función da -1 en caso de error. lista->fin = nuevo_elemento. lista->tamaño++. if ((nuevo _elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1. lista->inicio = nuevo_elemento. strcpy (nuevo_elemento->dato.

La función: /* inserción al inicio de la lista */ int ins_inicio_lista (Lista * lista. if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1. } 5 . if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1. strcpy (nuevo_elemento->dato. char *dato){ Element *nuevo_elemento. return 0. lista->tamaño++. dato). nuevo_elemento->siguiente = lista->inicio lista->inicio = nuevo_elemento.

Inserción al final de la lista Ejemplo de la función: int ins_fin_lista (Lista *lista. el puntero inicio no varía. el tamaño es incrementado: 6 . el puntero siguiente del último elemento apunta hacia el nuevo elemento. el puntero fin apunta al nuevo elemento. si no arroja 0. Element *actual. rellenar el campo de datos del nuevo elemento. Etapas: proporcionar memoria al nuevo elemento. La función da -1 en caso de error. char *dato).

lista->tamaño++. return 0. Element * actual. La inserción se efectuará después de haber pasado a la función una posición como argumento. if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1. char *dato){ Element *nuevo_elemento. strcpy (nuevo_elemento->dato.int pos). Si la posición indicada no tiene que ser el último elemento. si no da 0. } Inserción en otra parte de la lista Ejemplo de la función: int ins_lista (Lista *lista. actual->siguiente = nuevo_elemento. La función arroja -1 en caso de error. nuevo_elemento->siguiente = NULL. 7 . En ese caso se debe utilizar la función de inserción al final de la lista. if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1. dato). char *dato.La función: /*inserción al final de la lista */ int ins_fin_lista (Lista * lista. lista->fin = nuevo_elemento.

escoger una posición en la lista (la inserción se hará luego de haber elegido la posición). el puntero siguiente del nuevo elemento apunta hacia la dirección a la que apunta el puntero siguiente del elemento actual. el puntero siguiente del elemento actual apunta al nuevo elemento. los punteros inicio y fin no cambian. el tamaño se incrementa en una unidad: 8 .Etapas: asignación de una cantidad de memoria al nuevo elemento. rellenar el campo de datos del nuevo elemento.

for (i = 1. actual->siguiente = nuevo_elemento. i < pos. return 0.La función: /* inserción en la posición solicitada */ int ins_lista (Lista * lista. nuevo_elemento->siguiente = actual->siguiente. strcpy (nuevo_elemento->dato. dato). char *dato. int i. if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1. 9 . if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1. Element *nuevo_elemento. ++i) actual = actual->siguiente. if (pos < 1 || pos >= lista->tamaño) return -1. if (actual->siguiente == NULL) return -1. Element *actual. lista->tamaño++. int pos){ if (lista->tamaño < 2) return -1. actual = lista->inicio.

Eliminación de un elemento de la lista Para eliminar un elemento de la lista: uso de un puntero temporal para almacenar la dirección de los elementos a borrar. apuntar el puntero siguiente del elemento actual en dirección del puntero siguiente del elemento a eliminar. Etapas: el puntero sup_elem contendrá la dirección del 1er elemento. liberar la memoria ocupada por el elemento borrado. el tamaño de la lista disminuirá un elemento: 10 . actualizar el tamaño de la lista. de lo contrario da 0. el puntero inicio apuntara hacia el segundo elemento. Para eliminar un elemento de la lista hay varios casos: eliminación al inicio de la lista y eliminación en otra parte de la lista. el elemento a eliminar se encuentra después del elemento actual. La función devolverá -1 en caso de equivocación. Eliminación al inicio de la lista Ejemplo de la función: int sup_inicio (Lista *lista).

free (sup_elemento). Element *sup_elemento. lista->inicio = lista->inicio->siguiente. lista->tamaño--. if (lista->tamaño == 1) lista->fin = NULL. free (sup_elemento->dato). return 0. } 11 . sup_element = lista->inicio.La función: /* eliminación al inicio de la lista */ int sup_inicio (Lista * lista){ if (lista->tamaño == 0) return -1.

El tamaño de la lista será disminuido en un elemento: 12 . Si el elemento actual es el penúltimo elemento. el puntero siguiente del elemento actual apuntara hacia el elemento al que apunta el puntero siguiente del elemento que sigue al elemento actual en la lista. Etapas: el puntero sup_elem contendrá la dirección hacia la que apunta el puntero siguiente del elemento actual. si no devuelve 0. La función da -1 en caso de error. el puntero fin debe ser actualizado.Eliminación en otra parte de la lista Ejemplo de la función: int sup_en_lista (Lista *lista. int pos).

La función: /* eliminar un elemento después de la posición solicitada */ 13 .

} } Destrucción de la lista Para destruir la lista entera. return 0. int i. 14 . i < pos. actual = lista->inicio. } Visualización de la lista Para mostrar la lista entera hay que posicionarse al inicio de la lista (el puntero inicio lo permitirá). he utilizado la eliminación al inicio de la lista porque el tamaño es mayor a cero. if(actual->siguiente == NULL) lista->fin = actual. free (sup_elemento->dato). La condición para detener es proporcionada por el puntero siguiente del último elemento que vale NULL. Element *sup_elemento. while (actual != NULL){ printf ("%p . ++i) actual = actual->siguiente. for (i = 1. sup_elemento = actual->siguiente. free (sup_elemento). La función: /* visualización de la lista */ void visualización (Lista * lista){ Element *actual. actual->siguiente = actual->siguiente->siguiente. lista->tamaño--. Element *actual. actual->dato). actual = actual->siguiente.int sup_en_lista (Lista * lista. actual = lista->inicio. Luego usando el puntero siguiente de cada elemento la lista es recorrida del primero al último elemento.%s\n". actual. int pos){ if (lista->tamaño <= 1 || pos < 1 || pos >= lista->tamaño) return -1.

y las lecturas siempre eliminan el nodo leído. Estas características implican un comportamiento de lista LIFO (Last In First Out). Como consecuencia. los elementos de una pila serán eliminados en orden inverso al que se insertaron. respectivamente "empujar" y "tirar". } Pilas Las pilas son otro tipo de estructura de datos lineales. Es decir. el último en entrar es el primero en salir. las escrituras de datos siempre son inserciones de nodos. Estas operaciones se conocen como "push" y "pop". Una pila es una lista de elementos en la que se pueden insertar y eliminar elementos sólo por uno de los extremos. 15 . Una pila es un tipo especial de lista abierta en la que sólo se pueden insertar y eliminar nodos en uno de los extremos de la lista. Tipo de dato Abstracto Pila. las cuales presentan restricciones en cuanto a la posición en la cual pueden realizarse las inserciones y las extracciones de elementos.La función /* destruir la lista */ void destruir (Lista *lista){ while (lista->tamaño > 0) sup_inicio (lista). el último elemento que se metió a la pila será el primero en salir de ella. Además.

se puede cambiar*/ typedef char elemento. El tipo elemento variará dependiendo del programa. por esta razón las pilas se conocen como un TDA de acceso restringido. } else{ return 0. no existen bifurcaciones al momento de acceder a los datos. Operaciones: Vacia: int vacia(pila1) pila pila1.Tipo de dato Abstracto Pila en el que los elementos de almacenan de manera secuencial. /*va a ser una pila de caracteres*/ typedef struct { int tope. { if(pila1. { if((pila1.tope==tam_max){ return 1.tope)==0){ return 1. } pila. Pilas con vectores. } else{ return 0. } 16 . } }/*Fin esta vacia*/ Esta función devuelve 1 si la pila está vacía y 0 si no lo está. Implementación de pila: #define tam_max 20 /*el tamaño maximo sera 20. llena: int llena(pila1) pila pila1. así como tam_max. se acceden por medio de la dirección de memoria. Solo se puede eliminar o insertar por el tope. elemento v[tam_max]. Los elementos se pueden insertar o acceder por un único extremo llamado tope.

} }/*Fin meter*/ 17 . Meter: int meter(lo_que_meto. } else{ copia_tope=(*punt_pila). sacar: int sacar(punt_pila) pila *punt_pila.tope+1. if(valor_vacia==1){ return 0. } else{ (*punt_pila).punt_pila) elemento lo_que_meto. (Aplicar SACAR a una pila vacía la deja igual). return 1.}/*fin llena*/ Esta función devuelve 1 si la pila está llena y 0 si no lo está. pila *punt_pila.tope=copia_tope-1. } }/*fin sacar*/ Esta función elimina el elemento cima de la pila y devuelve 1 si la pila no está vacía y simplemente devuelve 0 si la pila está vacía. valor_vacia=vacia(*punt_pila). (*punt_pila). int valor_vacia.v[copia_tope-1]=lo_que_meto. valor_llena=llena(*punt_pila). int copia_tope.tope. (*punt_pila). if(valor_llena==1){ return 0. { int llena().tope=(*punt_pila). return 1. { int vacia(). int valor_llena.

pero esto se puede cambiar*/ struct Node *sgte.Esta función mete el elemento lo_que_meto en la pila y devuelve 1 si no está vacía y simplemente devuelve 0 si está llena. se puede cambiar*/ typedef struct Node{ /*defino el tipo nodo como registro de info y sgte*/ elemento info./*defino elemento como char. typedef nodo *pila.} else{ printf("\n Error. /*defino el tipo pila como puntero a nodo*/ El tipo elemento variará según el programa. Por eso hay que asegurarse de que la pila no está vacía antes de llamar a Cima.v[1]. /*en ppio las pilas seran de char.tope.}/*esto ultimo es absurdo. }. 18 . if(vacia(pila1)==0){ /*si no esta vacia se procede*/ copia_tope=pila1. { int vacia(). return pila1. typedef struct Node nodo. int copia_tope. { if (pila1==NULL) else return 0. Operaciones: Vacia: int vacia(pila1) pila pila1. Has aplicado la funcion cima a una pila vacia\n").v[copia_tope]. pero te ahorra un warning al compilar*/ }/*Fin Cima*/ Esta función devuelve el elemento cima si la pila no está vacía y devuelve un elemento de tipo elemento si está vacía dando un mensaje de error. Pila como Lista Enlazada typedef char elemento. pues la pila esta vacia. }/*Fin vacia*/ return 1. return pila1. Cima: elemento cima(pila1) /*1º hay q asegurarse d q no esté vacía*/ pila pila1.

} }/*Fin sacar*/ Sacar saca un elemento de la pila si no está vacía devolviendo 1 o devuelve 0 si está vacía. pila *punt_pila. luego quiero modificar su contenido: */ aux_pila=(*(*punt_pila)). } else{ /*se ha podido reservar espacio para un nodo: se procede a meter*/ (*(*punt_pila)).Vacía devuelve 1 si la pila está vacía y 0 si no lo está.sgte. q es un puntero al 1er nodo. /* pila1=*punt_pila */ if(*punt_pila==NULL){ printf("\n Error. } else{ /* (*punt_pila)es igual a pila1. No se puede reservar mas espacio. if(vacia(*punt_pila)==1){ return 0.sizeof(nodo))."). { pila aux_pila. /* (**punt_pila) apunta al 1er nodo*/ (*(*punt_pila)). aux_pila=*punt_pila.info=lo_que_meto. return 1. Sacar: int sacar(punt_pila) pila *punt_pila.sgte=aux_pila. *punt_pila=aux_pila. /*asi me hago una copia de pila1 en aux_pila*/ *punt_pila=(nodo*)calloc(1. pila aux_pila. /*para q el 1er nodo apunte al q ahora es el 2º*/ return 1.punt_pila) elemento lo_que_meto. return 0. free(*punt_pila). } }/*Fin meter*/ 19 . Meter: int meter(lo_que_meto. { int vacia().

}/*esto ultimo es absurdo.h> #include <conio. char telefono[25]. return ((*pila1). Cima: elemento cima(pila1) pila pila1.h> struct agenda { char nombre[50].info). pero te ahorra un warning al compilar*/} /*Fin vacia*/ Cima devuelve el elemento cima de una pila no vacía.h> #include <stdlib. Ejemplo Pilas: #include <stdio. Has aplicado la funcion cima a una pila vacia\n"). struct nodo *nuevonodo(). así que hay que asegurarse antes de ejecutarla. int colavacia(struct nodo *). struct nodo *proximo.info).h> #include <string. if(vacia(pila1)==0){/*no vacia*/ return ((*pila1). struct nodo { struct agenda dato. }.} else{ printf("\n Error. 20 . Si se aplica sobre una función vacía el programa aborta. }. pues la pila esta vacia.Meter mete lo_que_meto en la pila en caso de que no esté llena devolviendo un 1 o da un mensaje de error y devuelve un 0 en caso de que no haya más espacio en memoria para otro nodo. char mail[50]. { int vacia().

if(pri==NULL) pri=ult. printf("Ingrese mail: "). 21 . gets(x.nombre). while(strcmpi(x. void mostrar(struct nodo *). } struct nodo *nuevonodo() { struct nodo *p.nombre.struct nodo *creacola(struct nodo *. void main() { struct nodo *pri=NULL. // Si es la 1º pasada pongo en pri el valor del primer nodo printf("Ingrese nombre: ")."fin")) { printf("Ingrese telefono: "). *ult=NULL.nombre). ult=creacola(ult. } return p. printf("Ingrese nombre: "). struct agenda x. getch(). gets(x. gets(x. } if(colavacia(pri)==1) { printf("No se ingresaron registros"). if(p==NULL) { printf("Memoria RAM Llena"). exit(0). } struct nodo *creacola(struct nodo *ult.telefono).x). getch(). struct agenda). p=(struct nodo *)malloc(sizeof(struct nodo)). gets(x.mail). } else mostrar(pri). struct agenda x) { struct nodo *p.

nombre. pri=(*pri). else return 0.mail). 22 .pri>dato.p=nuevonodo(). while(pri!=NULL) { printf("Nombre: %s .proximo.pri->dato.dato=x.pri->dato. free(aux).proximo=NULL. } int colavacia(struct nodo *pri) { if(pri==NULL) return 1. if(ult!=NULL) (*ult).telefono.Telefono: %s . (*p). aux=pri.Mail: %s \n". } Colas. (*p). // Si hay nodo anterior en prox pongo la direccion del nodo actual return p. } getch().proximo=p. } void mostrar(struct nodo *pri) { struct nodo *aux.

llamado frente. Esta es una variación de la implementación en el libro C & Data Structures de una cola ( FIFO ) construida sobre un array. insertar): se añade un elemento a la cola. entrar. first out” (primero en entrar. transportes y operaciones de investigación (entre otros). front): se devuelve el elemento frontal de la cola. Encolar (añadir.Una cola es una colección de elementos homogéneos (almacenados en dicha estructura). el primer elemento que entró. es decir. Se añade al final de esta. Operaciones Básicas     Crear: se crea la cola vacía. Por esta razón la cola es denominada una estructura F.O.I. Así mismo. son los únicos indicados para retirar e insertar elementos. eliminar): se elimina el elemento frontal de la cola. Este tipo de estructura de datos abstracta se implementa en lenguajes orientados a objetos mediante clases. personas o eventos son tomados como datos que se almacenan y se guardan mediante colas para su posterior procesamiento. o sea el que está o se encuentra en el frente. tanto el frente como el final de la cola. esto representa el acrónimo de las palabras inglesas “first in.. el primer elemento que entró. es decir. los elementos sólo se pueden eliminar por el principio y sólo se pueden añadir por el final de la cola.. Esto nos indica que no podemos acceder directamente a cualquier elemento de la cola. Desencolar (sacar.I. y retirar los mismos por el otro extremo. en forma de listas enlazadas. primero en salir). o simplemente una lista F. y no se pueden insertar elementos en cualquier posición sino solo por el final. salir. Es importante aclarar que.O.F. Me intereso esa estructura de datos por 2 23 . Frente (consultar.F. denominado final. en la misma se pueden insertar elementos por uno de los extremos. Usos concretos de la cola La particularidad de una estructura de datos de cola es el hecho de que sólo podemos acceder al primer y al último elemento de la estructura. Las colas se utilizan en sistemas informáticos. sino solo al primero. respectivamente. así el elemento insertado queda como último. dónde los objetos.

Así que esta es una implementación. } else { temp = carr->cola[ carr->frente ]. Sin embargo. el hecho de que la estructura de datos era más que el array donde se guardaban los datos. Primero. int value ) { if(carr->frente == carr->fin && carr->num_elems > 0) { printf("Cola Llenan"). int num_elems. carr->num_elems ++. en la sintaxis de punteros y de structs en C: #include <stdio. lo lógico sería agrupar todas estas variables dentro de un struct de C. int fin. int frente.h> #include <stdlib. void insert( cola_array *carr. if( carr->num_elems == 0 ) { printf("Cola Vacian").h> #define MAX 10 /* The maximum size of the queue */ struct ca { int cola[ MAX ]. carr->fin = ( carr->fin + 1) % MAX.cosas. necesitándose una serie de variables asociados para usarlo y segundo el uso de la aritmética mod( n ) para moverse entre las posiciones del array. } else { carr->cola[ carr->fin ] = value. }. } } int delete( cola_array *carr ) { int temp. existen una serie de errores en la implementación del ejemplo y además considerando que se utilizan un conjunto de variables para definir el funcionamiento de la estructura. typedef struct ca cola_array. return -1. 24 .

carr->frente. } } void listar( cola_array *carr ) { int x. case 2: value = delete( &carr ). Insertarn"). for( x = 0. cola_array carr. x++) { printf("%dt".frente = carr. carr->cola[ ( x + carr->frente ) % MAX ]).fin = carr. carr->fin).carr->frente = ( carr->frente + 1) % MAX. printf("3. carr. break. return temp. insert( &carr. &menu). Listarn"). printf("4. value). } else { printf("Numero de Elementos: %dt Frente: %dt Fin: %dn". } int main() { int menu. printf("2. carr->num_elems--. carr>num_elems. Salirn"). Borrarn").num_elems = 0. scanf("%d". } } printf("n"). if( carr->num_elems == 0 ) { printf("Cola Vacia"). value. x < carr->num_elems. &value). if(value >= 0) { 25 . printf("1. do { printf("Seleccione:n"). switch(menu) { case 1: printf("Valor a Insertar (Mayor o Igual que 0): n"). scanf("%d".

0. de la misma manera que 1/10. 11/10. pero como la cola ya se estuvo utilizando quedaron ubicados los 2 primeros en las posiciones 8 y 9 del array y los 3 últimos en las posiciones 0 a 2. return(0).printf("Valor borrado: %d n". Esto es así porque en la 0/10. case 3: listar( &carr ). Colas como Listas enlazadas 26 . x < carr->num_elems. x++) { printf("%dt". } Y en particular ( x + carr->frente ) % MAX por el uso de la aritmética mod( n ) que me hizo recordar al concepto de clases de equivalencias de Algebra Explicación: Supongamos que la cola tiene 5 elementos (sobre un máximo de 10).. tienen exactamente el mismo resto. value). } break. break. El loop va a iterar a x de 0 a 4. } } while( menu != 4 ). break. break. etc. ( x + carr->frente ) equivale a 10 y 10 % MAX equivale a 0. cuando x este en 0 ( x + carr->frente ) % MAX va a equivaler a 8. etc tienen todos resto 1. cuando este en 1 a 9. case 4: return(0). default: printf("Opcion no Valida. carr->cola[ ( x + carr->frente ) % MAX ]). pero cuando llegue a 2. Lo que permite moverse circularmente sobre el array. } La parte que más importante es esta: for( x = 0..n"). ( La operación % establece clases de equivalencia sobre N). 10/10. 20/10. 21/10.

Declaración: struct tcola { int clave. struct tcola *sig. . Partiendo de la cola formada anteriormente. Cuando se añadan elementos el puntero que mantiene la cola apunta al último elemento introducido. Si no está vacía hay que actualizar el enlace del. La cola estará inicialmente vacía. último elemento introducido. se van añadiendo el 5 y el 7 (observar de izquierda a derecha).¿Cómo encolar? Se crea el nuevo elemento. Ejemplo gráfico de encolado. se enlaza con el primero de la cola. se han quitado los dos primeros elementos introducidos (observar de izquierda a derecha). Partiendo de una cola que tiene el elemento 3. . y el siguiente elemento al que apunta es al primero que está esperando para salir. 27 . hasta el momento de la inserción. A la hora de desencolar se extrae el siguiente al que apunta Cola.¿Cómo desencolar? Si tiene un sólo elemento se borra y se actualiza el puntero a un valor nulo. .Para hacer la implementación se utilizará una lista circular sin cabecera. esté vacía o no. Ejemplo gráfico de desencolado. Si tiene dos o más elementos entonces se elimina el primero y el último apuntará al segundo. Por último se actualiza el comienzo de la cola.

Encolado: void encolar(struct tcola **cola. int elem) { struct tcola *nuevo.Creación: void crear(struct tcola **cola) { *cola = NULL.Desencolado: void desencolar(struct tcola **c1.}. } (*cola) = nuevo. nuevo = (struct tcola *) malloc(sizeof(struct tcola)). } . } . (*cola)->sig = nuevo. nuevo->clave = elem. else { nuevo->sig = (*cola)->sig. . int *elem) { struct tcola *aux. if (*cola == NULL) nuevo->sig = nuevo.Función que devuelve cierto si la cola está vacía: int vacia(struct tcola *cola) { return (cola == NULL). } . 28 .

h> int main(void) { struct tcola *cola. Otras consideraciones 29 . crear(&cola). 3).Programa de prueba: #include <stdio.c para tener una implementación completa con listas enlazadas. int elem. &elem). } } . return 0.*elem = (*c1)->sig->clave. (*c1)->sig = aux->sig. encolar(&cola. es recomendable analizar el código devuelto por la función de asignación de memoria para evitar posibles problemas en un futuro. desencolar(&cola. if ((*c1) == (*c1)->sig) { free(*c1). Al igual que en las pilas implementadas por listas enlazadas. *c1 = NULL. } else { aux = (*c1)->sig.h> #include <stdlib. free(aux). } Ver colasle. if (vacia(cola)) printf("\nCola vacia!").

/* mantiene el numero de elementos */ struct nodo *cola. struct tcola { int numero_elems. Si se conocen de antemano el número de elementos entonces lo ideal es una implementación por array. }. Una manera de hacer esto con listas enlazadas es empleando la siguiente declaración: struct nodo { int clave. 30 .En algunos casos puede ser interesante implementar una función para contar el número de elementos que hay en la cola. }. En otro caso se recomienda el uso de lista enlazada circular. ¿Qué implementación es mejor. struct nodo *sig. arrays o listas? Al igual que con las pilas. la mejor implementación depende de la situación particular.