Colas en C

davidpoza

Buenas noches,
Me duele la cabeza de tanto darle vueltas a un programa que estoy haciendo, que pretende implementar el tad cola, en c.
Llevo muy poco con este lenguaje, ya habia hecho una implementación en pascal, pero veo me esto del c es mucho mas jodio.

Lo que tengo es esto:

/cola de enteros dinámica/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define TRUE 1
#define FALSE 0
#define OK 0
#define ERROR 1

typedef struct elemento{
int valor;
struct elemento sig; /puntero a un tipo elemento*/
}tipo_elemento ;

typedef struct cola{
tipo_elemento *cabeza, *final;
} tipo_cola;

void inicializar_cola(tipo_cola *cola);
int cola_vacia(tipo_cola cola);
int num_elems_cola(tipo_cola cola);
int cabeza(tipo_cola cola);
void encolar (tipo_cola *cola, int elemento);
void desencolar(tipo_cola *cola);
void imprimir(tipo_cola cola);

int main(void)
{
char op;
int elemento;
tipo_cola cola;
inicializar_cola(&cola);
do
{
printf("Implementacion de colas con punteros\n\n");
printf("1. Encolar elemento\n");
printf("2. Desencolar elemento\n");
printf("3. Ver elementos\n");
printf("4. Finalizar programa\n");
if (cola_vacia(cola)) printf("vacia\n");
printf("\nEn este momento la cola tiene %d elementos.\n", num_elems_cola(cola));
op=getch(); /ojo lleva parentesis/
switch (op)
{
case '1':
printf("Escribe el elemento a encolar: ");
scanf("%d", &elemento);
encolar(&cola, elemento);
break;
case '2':
if (!cola_vacia(cola))
{
printf("Desencolando elemento \"%d\" de la primera posicion\n", cabeza(cola));
desencolar(&cola);
}
else
printf("Es imposible desencolar algo si NO HAY ELEMENTOS x(\n");
break;
case '3':
if (!cola_vacia(cola))
{
printf("Los elementos de la cola son:\n");
imprimir(cola);
}
else
printf("Imposible mostrar los elementos porque NO HAY!\n");
break;
}

}

while (op!='4');
return 0;
}

void inicializar_cola(tipo_cola *cola)
{
cola->cabeza=NULL;
cola->final=NULL;
}

int cola_vacia(tipo_cola cola)
{
if (cola.cabeza==NULL && cola.final==NULL)
return TRUE;
else
return FALSE;
}

int num_elems_cola(tipo_cola cola)
{
int n=0;
while (cola.cabeza != NULL)
{
cola.cabeza=cola.cabeza->sig;
n++;
}
return n;
}

int cabeza(tipo_cola cola)
{
return cola.cabeza->valor;
}

void encolar (tipo_cola *cola, int elemento)
{
tipo_elemento aux;
aux=(tipo_elemento
)malloc(sizeof(tipo_elemento));
aux->valor=elemento;
aux->sig=NULL;
if (cola_vacia(*cola))
cola->cabeza=aux;
else
cola->final->sig=aux;
cola->final=aux;
}

void desencolar(tipo_cola *cola)
{
tipo_elemento *aux;
aux=cola->cabeza;
cola->cabeza=cola->cabeza->sig;
if (cola->cabeza=NULL)
cola->final=NULL;

free(aux);

}

void imprimir(tipo_cola cola)
{
int linea=1;
while (cola.cabeza!=NULL)
{
printf("%d. %d\n", linea, cola.cabeza->valor);
cola.cabeza=cola.cabeza->sig;
linea++;
}
}


Realmente no se muy bien dónde puede estar el fallo, supongo que en la función encolar o desencolar, pero no estoy seguro.
El problema que da es en tiempo de ejecución, una violación de esas que salen hasta debajo de las piedras :). Encolo un elemento y todo perfecto, lo indica y lo muestra correctamente, ahora lo desencolo y todo de puta madre, pero si vuelvo a encolar otra vez ya no se entera, ni lo marca ni nada y entonces, como es como si se hubiera encolado nada, me peta al intentar desencolar.

Si alguien controla el tema o tiene ejemplos, o links o algo que me oriente, muchas gracias...;)

JJeNnY

Puf despues de echarle un vistazo en el compilador no saco el error, creo q peude estar en una perdida de direccion cuando intentas insentar el nuevo valor en la 2º pasada ( encolar ), pero vamos no le saco el error, te dejo un ejemplo de como nos explicaron a nosostros el mismo tema en C.
Desde entonces mis programas arrastraron siempre el *pActual y *pSiguiente, espero q te sirva, y ya le dare otro repaso alo tuyo.

pragma hdrstop
#include <condefs.h>
#include
#include <conio.h>
/*
ListaLineal con ordenacion de entradas
*/

struct tR
{
char sDatos[22];
struct tR *pSiguiente;
};

void insertar ( tR **pLista , char sDatos[] );
void ListarLista( tR *pCabecera );

void main ()
{
struct tR *pLista;
pLista = NULL;
char sNombre[22];

for (;; )
{
printf("Dame un nombre, * para salir: ");
scanf ("\n%s", &sNombre );

if( strcmpi( sNombre , "*" ) != 0 )
insertar ( &pLista, sNombre );
else
break;
}


ListarLista(pLista);
getch();
}

void insertar( tR **pLista , char sDatos[] )
{
struct tR *pActual;
struct tR *pAnterior;
struct tR *pNueva;


pNueva = (struct tR *) malloc( sizeof (struct tR )); // se crea la caja de la nueva entrada
strcpy( pNueva->sDatos,sDatos); // se le añande el campo nombre

pAnterior = pActual = *pLista;
while ( pActual != NULL && strcmp( pActual->sDatos,sDatos) < 0 ) // recorremos las cajas buscando el sitio
{
pAnterior = pActual;
pActual = pActual->pSiguiente;
}

if ( pAnterior == NULL || pAnterior == pActual)// si cumple va antes q la ultima caja comprovada
{
    pNueva->pSiguiente = pAnterior;
    *pLista = pNueva;               //si se situa antes se cambia la cabecera para no perder la anterior
}

else      // si no cumple va en medio de la ultima y la anterior, o detras d la ultima
{
    pNueva->pSiguiente = pActual;
    pAnterior->pSiguiente = pNueva;
}

}
void ListarLista( struct tR *pCabecera )
{
struct tR *pActual;
int iFila = 5;

pActual = pCabecera;
clrscr();
gotoxy( 2,5);
printf("LISTADO DE NOMBRES");

while( pActual )
{
gotoxy( 5, ++iFila );
if( iFila > 23 )
iFila = 5;
printf(" : %s ",pActual->sDatos );
pActual= pActual->pSiguiente;
}
gotoxy( iFila+2,24 );
printf( "Pulse una tecla para salir...." );
}

cabron

Lo has hecho algo complicado, no es necesario una estructura para una cola, con un array te vale.

Aquí tienes un ejemplo de como se harían las operaciones básicas de una cola en C (lo he escrito directamente, no lo he compilado así que no se si da algún error y a lo mejor me he colado en algo):

http://www.rafb.net/paste/results/Epib8I97.html

gF

Sabiendo que el fallo está en desencolar es facil detectarlo:

En esa funcion tienes puesto:

if (cola->cabeza=NULL)

Cuando deberia ser:

if (cola->cabeza==NULL)

davidpoza

Muchas gracias!
parece que ya tira. Como decia antes, vengo de pascal y me cuesta acostumbrarme a estos cambios:
antes = ahora ==.

Usuarios habituales

  • davidpoza
  • gF
  • cabron
  • JJeNnY