Colas en c ejemplo

Capítulo 11 Colas, colas de prioridad y montículos EJEMPLO 11.1 Representación gráfica de la colocación y eliminación de

Views 110 Downloads 1 File size 394KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Capítulo 11 Colas, colas de prioridad y montículos EJEMPLO 11.1 Representación gráfica de la colocación y eliminación de elementos en una cola implementada con arrays.

Tras extraer un elemento las posiciones de frente y final son:

Si ahora se añade un elemento

Esta implementación tiene como inconveniente que puede ocurrir que la variable final llegue al valor máximo de la tabla, con lo cual no se puedan seguir añadiendo elementos a la cola, aún cuando queden posiciones libres a la izquierda de la posición frente .

EJEMPLO 11.2 #include typedef struct nodo { TipoDato elemento; struct nodo* siguiente; }Nodo; typedef struct { Nodo* frente; Nodo* final; }Cola; /* prototipos de las operaciones */ void crearCola(Cola* cola); void insertar(Cola* cola, TipoDato entrada); TipoDato quitar(Cola* cola); void borrarCola(Cola* cola); /* libera todos los nodos de la cola */ /* acceso a la cola */ TipoDato frente(Cola cola);

1

2

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

/* métodos de verificación del estado de la cola */ int colaVacia(Cola cola);

EJEMPLO 11.3

EJEMPLO 11.4

Colas, colas de prioridad y montículos

Problema 11.1 #include #include #define MAXIMO 100 typedef float TipoElemento; typedef struct { TipoElemento A[MAXIMO]; int frente, final; }Cola; int sig (int n) { return (n + 1) % MAXIMO; } void VaciaC(Cola* C); void AnadeC(Cola* C, TipoElemento e); void BorraC(Cola* C); TipoElemento PrimeroC(Cola C); int EsvaciaC(Cola C); int EstallenaC(Cola C); void VaciaC(Cola* C) { C->frente = 0; C->final = MÁXIMO - 1; } void AnadeC(Cola* C, TipoElemento e) { if (EstallenaC(*C)) { puts("Cola completa"); exit (1); } C->final= sig(C->final); C->A[C->final] = e; }

3

4

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

int EstallenaC(Cola C) { return C.final == sig(sig(C.frente)); } void BorraC(Cola* C) { if (EsvaciaC(*C)) { puts(" Se intenta sacar un elemento en C vacía"); exit (1); } C->frente = sig( C->frente); } int EsvaciaC(Cola C) { return C.final == sig(C.frente); } TipoElemento PrimeroC(Cola C) { if (EsvaciaC(C)) { puts(" Error de ejecución, C vacía"); exit (1); } return C.A[C.frente]; }

Problema 11.2 #include #include typedef int TipoElemento; struct nodoCola { TipoElemento e; struct nodoCola* sig; } NodoCola; typedef struct { NodoCola * Frente,* Final; }Cola;

/* prototipos de las operaciones */

void VaciaC(Cola* C) { C->Frente = NULL; C->Final = NULL; } int EsVaciaC(Cola C) { return (C.Frente == NULL); } void AnadeC(Cola* C,TipoElemento e) { NodoCola* a; a = (NodoCola*)malloc(sizeof(NodoCola)); a->e = e; a->sig = NULL; if (EsVaciaC(*C)) C->Frente = a; else C->Final->sig = a; C->Final = a; } void {

BorrarC(Cola* C)

Colas, colas de prioridad y montículos

NodoCola *a; if (!EsVaciaC(*C)) { a = C->Frente; C->Frente = C->Frente->sig; if(C->Frente == NULL) C->Final = NULL; free(a); } else { puts("Error eliminacion de una cola vacía"); exit(-1); } } TipoElemento PrimeroC(Cola C) { if (EsVaciaC(C)) { puts("Error: cola vacía"); exit(-1); } return (C.Frente->e); }

Problema 11.3

..... typedef NodoCola *Cola; ...... void VaciaC(Cola* C) { *C = NULL; } int EsVaciaC(Cola C) { return (C == NULL); } void AnadeC(Cola* C,TipoElemento e) { NodoCola* a; a = (NodoCola*)malloc(sizeof(NodoCola)); a->e = e; if (! EsVaciaC(*C)) { a->sig = (*C)->sig;

(*C)->sig = a;

} else a->sig = (*C); *C = a; } void BorrarC(Cola* C) { NodoCola *a; if (!EsVaciaC(*C)) { a = (*C)->sig; if(a == *C) (*C) = NULL; else (*C)->sig = a->sig; free(a);

5

6

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

} else { puts("Error eliminacion exit(-1); }

de una cola vacía");

} TipoElemento PrimeroC(Cola C) { if (EsVaciaC(C)) { puts("Error: cola vacía"); exit(-1); } return (C->sig->e); }

Problema 11.4 #include #include #include typedef int Telemento; struct Puntero { Telemento Info; struct Puntero *Sig, *Ant; }puntero; typedef struct { puntero *Frente, *Final; }Bicola; void int void void void void void void

VaciaBi(Bicola* B); EsvaciaBi(Bicola B); AnadeBiP( Bicola *B, Telemento e); AnadeBiF( Bicola *B, Telemento e); PrimeroBP(Bicola B,Telemento *e); PrimeroBF(Bicola B, Telemento *e); BorraBiP(Bicola *B); BorraBiF( Bicola *B);

void VaciaBi(Bicola* B) { (*B).Frente = NULL; (*B).Final = NULL; } int EsvaciaBi(Bicola B) { return B.Frente == NULL; } void AnadeBiP( Bicola *B, Telemento e) { puntero *aux; aux = (puntero*)malloc(sizeof(puntero)); aux->Info = e; aux->Ant = NULL; aux->Sig = (*B).Frente; if ((*B).Frente == NULL) (*B).Final = aux; else (*B).Frente->Ant = aux; (*B).Frente = aux; }; void AnadeBiF( Bicola *B, Telemento e)

Colas, colas de prioridad y montículos

{ puntero *aux; aux = (puntero*)malloc(sizeof(puntero)); aux->Info = e; aux->Sig = NULL; aux->Ant =(*B).Final; if ((*B).Final == NULL) (*B).Frente = aux; else (*B).Final->Sig = aux; (*B).Final = aux; }; void PrimeroBP(Bicola B, Telemento *e) { if (B.Frente != NULL) *e = B.Frente->Info; }; void PrimeroBF( Bicola B, Telemento *e) { if (B.Final != NULL) *e = B.Final->Info; }; void BorraBiP( Bicola *B) { puntero *aux; if ((*B).Frente != NULL) { aux = (*B).Frente; if ((*B).Frente == (*B).Final) { (*B).Frente = NULL; (*B).Final = NULL; } else { (*B).Frente = aux->Sig; (*B).Frente->Ant = NULL; } aux->Sig = NULL; free(aux); } } void BorraBiF( Bicola *B) { puntero *aux; if ((*B).Final != NULL) { aux = (*B).Final; if ((*B).Frente == (*B).Final) { (*B).Frente = NULL; (*B).Final = NULL; } else { (*B).Final = aux->Ant; (*B).Final->Ant = NULL; } aux->Ant = NULL; free(aux); } }

Problema 11.5

7

8

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

void mostrarCola(Cola* C) { // muestra los elementos de una cola que TipoElemento e; while (!EsVaciaC(*C)) { e = PrimeroC(*C); printf("%d ", e); BorrarC(C); } }

se le pase como parámetro.

void main() { Cola C; int n, n1, n2, n3, i; randomize(); n = 1 + random(500); VaciaC(&C); for (i = 1; i final = sig(Bi->final); Bi->A[Bi->final] = e; } void AnadeBiP(Bicola* Bi, TipoElemento e) { if (EstallenaBi(*Bi)) { puts("BiCola completa"); exit (1); }

9

10

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Bi->frente = ant(Bi->frente); Bi->A[Bi->frente] = e; } void BorraBiP(Bicola* Bi) { if (EsvaciaBi(*Bi)) { puts(" Se intenta sacar un elemento en Bi vacía"); exit (1); } Bi->frente = sig( Bi->frente); } void BorraBiF(Bicola* Bi) { if (EsvaciaBi(*Bi)) { puts(" Se intenta sacar un elemento en Bi vacía"); exit (1); } Bi->final = ant( Bi->final); } TipoElemento PrimeroBiP(Bicola Bi) { if (EsvaciaBi(Bi)) { puts(" Error de ejecución, Bi vacía"); exit (1); } return Bi.A[Bi.frente]; } TipoElemento PrimeroBiF(Bicola Bi) { if (EsvaciaBi(Bi)) { puts(" Error de ejecución, Bi vacía"); exit (1); } return Bi.A[Bi.final]; }

Problema 11.8 #define Maxprio 12 typedef struct { int prioridad; char NombreT[20]; }Trabajo; typedef Trabajo TipoElemento; /* Gestión de una cola */ #include "cola.h"..... typedef struct { int NP; Cola colas[Maxprio]; } ColaPrioridad; void VaciaCp(ColaPrioridad* cp); void AnadeCP(ColaPrioridad* cp, Trabajo t); Trabajo PrimeroCp(ColaPrioridad cp); void BorrarCp(ColaPrioridad* cp); int EsvaciaCp(ColaPrioridad cp);

Colas, colas de prioridad y montículos

void VaciaCp(ColaPrioridad* cp) { int j; cp->NP = Maxprio; for (j = 0; j < Maxprio; j++) VaciaC(&(cp->colas[j])); } void AnadeCp(ColaPrioridad* cp, Trabajo t) { if ((1 < t.prioridad) && (t.prioridad NP)) AnadeC(&cp->colas[t.prioridad - 1],t); else puts("Trabajo con prioridad fuera de rango"); } Trabajo PrimeroCp(ColaPrioridad cp) { int i = 0, Icola = -1; /* búsqueda de la primera cola no vacía */ do { if (!EsvaciaC(cp.colas[i])) { ICola = i; i = cp.NP; /* termina el bucle */ } else i++; } while (i < cp.NP); if (ICola == -1) { puts("Cola de prioridades vacía"); exit(1); } return PrimeroC((cp.colas[ICola])); } void BorrarCp(ColaPrioridad* cp) { int i = 0,ICola=-1 ; /* búsqueda de la primera cola no vacía */ do { if (!EsvaciaC(cp->colas[i])) { ICola = i; i = cp->NP; /* termina el bucle */ } else i++; } while (i < cp->NP); if (ICola == -1) { puts("Cola de prioridades vacía"); exit(1); } BorraC(&(cp->colas[ICola])); } int EsVaciaCP(ColaPrioridad cp) { int i = 0; while (EsvaciaC(cp.colas[i]) && i < cp.NP - 1) i++; return EsvaciaC(cp.colas[i]); }

Problema 11.9

11

12

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Codificación #include #include typedef struct { int prioridad; char NombreT[20]; }Trabajo; typedef struct RegistroCP { Trabajo trabajo; struct RegistroCP* sig; }NodoCp; typedef NodoCp *ColaPrioridad; void VaciaCp(ColaPrioridad* Cp) { *Cp = NULL; } int EsvaciaCp(ColaPrioridad Cp) { return (Cp == NULL); } Trabajo PrimeroCp(ColaPrioridad Cp) { if(EsvaciaCp(Cp)) { printf (" cola de prioridad vacia"); exit(1); } return (Cp->trabajo); } void BorrarCp(ColaPrioridad* Cp) { NodoCp *ab; if(EsvaciaCp(*Cp)) { printf (" cola de priroridad vacia"); exit(1); } ab = *Cp; *Cp = ab->sig; free (ab); } void AnadeCpR(ColaPrioridad* Cp, Trabajo trabajo) { NodoCp *nuevonodo; if (*Cp == NULL) { nuevonodo = NuevoNodoCp(trabajo); *Cp = nuevonodo; } else if (trabajo.prioridad < (*Cp)->trabajo.prioridad) { nuevonodo = NuevoNodoCp(trabajo); nuevonodo->sig = *Cp; *Cp = nuevonodo; } else AnadeCpR(&((*Cp)->sig),trabajo); } void AnadeCp(ColaPrioridad* Cp, Trabajo trabajo) { NodoCp *nuevonodo, *ant, *p;

Colas, colas de prioridad y montículos

nuevonodo = NuevoNodoCp(trabajo); if (*Cp == NULL) *Cp = nuevonodo; else if (trabajo.prioridad < (*Cp)->trabajo.prioridad) { nuevonodo->sig = *Cp; *Cp = nuevonodo; } else { ant = p = *Cp; // se sabe que no es el primero while ((trabajo.prioridad > p->trabajo.prioridad) && (p->sig != NULL) ) { ant = p; p = p->sig; } if (trabajo.prioridad > p->trabajo.prioridad) // falta por comprobar el ultimo ant = p; nuevonodo->sig = ant->sig; ant->sig = nuevonodo; } }

NodoCp* NuevoNodoCp(Trabajo trabajo) { NodoCp *nuevonodo ; nuevonodo= (NodoCp*)malloc(sizeof(NodoCp)); nuevonodo->sig = NULL; nuevonodo->trabajo = trabajo; return nuevonodo; } void Escribir(ColaPrioridad Cp) { printf("\n\t\t Cola de prioridad \n"); for (; Cp; Cp = Cp->sig) printf(" %s %d \n",Cp->trabajo.NombreT, Cp->trabajo.prioridad); printf("\n\n"); } void main() { Trabajo trabajo; int d; ColaPrioridad Cp; Cp = NULL; do { printf(" Introduzca prioridad del trabajo scanf("%d", &trabajo.prioridad); if (trabajo.prioridad != -1) { puts(" nombre del trabajo "); scanf("%s", &trabajo.NombreT); AnadeCpR(&Cp,trabajo); } } while (trabajo.prioridad != -1); Escribir(Cp); do { printf(" borrar -1 = fin\n"); scanf("%d", &d); if (d != -1) BorrarCp(&Cp); Escribir(Cp); } while (d != -1); }

-1 = fin\n");

13

14

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Problema 11.10 #define MAXIMO 100 typedef int Telemento; typedef struct { Telemento a[MAXIMO+1]; int n; }Monticulo; void Subir(Monticulo* monticulo, int pos) { Telemento Clave; int padre, EsMonton=0; Clave = monticulo->a[pos]; padre = pos/2; while ((padre >= 1) && !EsMonton) if (monticulo->a[padre] > Clave) { monticulo->a[pos] = monticulo->a[padre]; pos = padre; padre=padre/2; } else EsMonton=1; monticulo->a[pos] = Clave; }

/*guarda el dato */

/* baja al hueco el padre */ /* sube un nivel en el árbol */

/* sitúa la clave en su posición*/

void Insertar (Monticulo* monticulo, Telemento Clave) { if (monticulo->n == MAXIMO) puts("No es posible insertar nuevas claves: montículo lleno"); else { (monticulo->n)++; monticulo->a[monticulo->n] = Clave; Subir(monticulo, monticulo->n); } } void CrearMonticulo(Monticulo* monticulo) { monticulo->n = 0; } int EsVacio (Monticulo monticulo) { return monticulo.n == 0; } Telemento BuscarMinimo(Monticulo monticulo) { if (monticulo.n == 0) puts( "monticulo vacio"); return monticulo.a[1]; } void Criba (int a[], int primero, int ultimo) { /* primero: indice del nodo raiz */ int EsMonticulo = 0, HijoMenor, aux; while ((2 * primero a[1] = monticulo->a[monticulo->n]; monticulo->n = monticulo->n - 1; Criba(monticulo->a, 1, monticulo->n); } }

Problema 11.11 #include #include #include #define Max2 100 /* operaciones del tipo abstracto de dato Montículo */.... void Rellena(Telemento A[Max2], int *n) { int i; randomize(); *n=random(Max2); for(i = 0; i < (*n); i++) A[i] = random(Max2); } void Escribe( Telemento A[], int n) { int i; for( i = 0; i < n; i++) if ( (i + 1) % 10 == 0) printf("%7d\n",A[i]); else printf("%7d",A[i]); } void main (void) { Telemento a[Max2]; int n,i; Monticulo monticulo; Rellena(a,&n); Escribe(a,n); CrearMonticulo(&monticulo); for(i = 0; i < n; i++) insertar (&monticulo, a[i]); for(i = 0; i < n; i++) { a[i] = BuscarMinimo(monticulo); EliminarMinimo(&monticulo); } printf(" datos ordenados\n");

15

16 }

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Escribe(a,n);

Problema 11.12 typedef struct { matricula[51]; } Coche; typedef Coche TipoElemento;

/*

cola y biola como se definen en los ejercicios 11.1 y 11.7 con 12 elementos como máximo */ void main() { Coche coche; char ch; Bicola Bi; Cola C; int continuar = 1; VaciaBi(&Bi); VaciaC(&C); while (continuar) { puts("\n Entrada de datos: [acción: i/d/I/D] "); puts("\n i retirar izquierda d retirar derecha "); puts("\n I omsertar izquierda D insertar derecha "); puts(" Para terminar la simulación: x"); do { scanf("%c%*c",&ch); } while(ch != 'i' && ch != 'd' && ch != 'I' && ch != 'D' && ch != 'x'); if (ch == 'i') { if (!EsvaciaBi(Bi)) { coche = PrimeroBiP(Bi); BorraBiP(&Bi); printf("Salida del coche: %s por la izquierda", coche.matricula); if (!EsvaciaC(C)) { // si hay cohes en cola d espera añadirlo coche = PrimeroC(C); BorraC(&C); AnadeBiP(&Bi,coche); } } } else if (ch == 'd') { if (!EsvaciaBi(Bi)) { coche = PrimeroBiF(Bi); BorraBiF(&Bi); printf("Salida del coche: %s por la derecha", coche.matricula); if (!EsvaciaC(C)) { // si hay coches en cola de espera añadirlo coche= PrimeroC(C); BorraC(&C); AnadeBiF(&Bi,coche); } } } else if (ch == 'I') { printf( " Introduzca matricula: " ); gets(coche.matricula); if (!EstallenaBi(Bi))

Colas, colas de prioridad y montículos

AnadeBiP(&Bi, coche); else /* No cabe en la bicola ponerlo en cola de espera*/ AnadeC(&C, coche); } else if (ch == 'D') { printf( " Introduzca matricula: " ); gets(coche.matricula); if (!EstallenaBi(Bi)) AnadeBiF(&Bi, coche); else // No cabe en la bicola ponerlo en cola de espera AnadeC(&C, coche); } continuar = !(ch == 'x'); } }

11.13 #include #include typedef struct { int Num_Trabajo, HoraLlegada, TiempoResta, HoraActual; } Datos; struct Nodo { Datos Info; Nodo *Sig; }; typedef struct Nodo *Lista; Lista c[2]; /* colas de prioridad */ int t[2]; /* Tiempos CPU */ int OtroNivel, Nivel, RelojSistema; void InsertarNivel (Lista *L, Datos r) { Lista Nuevo; if (*L == NULL) { *L= (Nodo*)malloc(sizeof(Nodo)); (*L)->Info = r; (*L)->Sig = NULL; } else if ( (*L)->Info.HoraActual Sig, r); else { Nuevo= (Nodo*)malloc(sizeof(Nodo)); Nuevo->Info = r; Nuevo->Sig = *L; *L = Nuevo; } } void SacarDeCola ( Lista *L, Datos *r) { Lista auxiliar; auxiliar = *L; *L = (*L)->Sig; *r = auxiliar->Info; free(auxiliar); }; void Inicializar ( Lista c[2]) { FILE *f; int nivel ;

17

18

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Datos r; if ((f = fopen("datos.dat","rt"))== NULL) { printf(" error en archivo texto"); exit(1); } while (!feof(f)) { fscanf(f,"%d%d%d%d\n",&r.Num_Trabajo,&r.HoraLlegada,&r.TiempoResta,&nivel); r.HoraActual = r.HoraLlegada; InsertarNivel (&c[nivel], r); } fclose(f); } void CogerTrabajo (Lista *L, int Tiempo) { Datos r; SacarDeCola (L, &r); if (r.HoraActual > RelojSistema) RelojSistema = r.HoraActual; if (r.TiempoResta > Tiempo) { r.TiempoResta -= Tiempo; RelojSistema += Tiempo; r.HoraActual = RelojSistema; InsertarNivel (L, r); } else { RelojSistema += r.TiempoResta; printf("Finaliza trabajo %d a la hora %d\n",r.Num_Trabajo,RelojSistema); } } void ElegirNivel (int *Nivel, int *OtroNivel, Lista c[2]) { if (c[*Nivel] ==NULL) *Nivel = *OtroNivel; else if (c[*OtroNivel] != NULL) { if (c[*OtroNivel]->Info.HoraActual Info.HoraActual > RelojSistema) /* compara */ if (c[*Nivel]->Info.HoraActual >= c[*OtroNivel]->Info.HoraActual) *Nivel = *OtroNivel; } } void main() { c[1] = NULL; c[2] = NULL; Inicializar (c); printf ("El orden de salida es"); if (c[2] == NULL) Nivel = 1; else if (c[1] == NULL) Nivel = 2; else if (c[1]->Info.HoraLlegada Info.HoraLlegada) Nivel = 1; else Nivel = 2; RelojSistema = 0; t[1] = 2;

Colas, colas de prioridad y montículos

t[2] = 1; while ((c[1] != NULL) || (c[2] != NULL)) { CogerTrabajo (&(c[Nivel]), t[Nivel]); OtroNivel = 3 - Nivel; /*Genera ElegirNivel (&Nivel, &OtroNivel, c); } }

valores 1,2 alternativamente*/

19