Algoritmi e Programmazione Avanzata - Liste, pile, code

22
stack.c /* Algoritmi e Programmazione Avanzata Tutore: Sergio Porcu Argomento: stack Gestione di uno stack con liste concatenate */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_STR 10 /* Utilizzo costanti locali invece di EXIT_SUCCESS e EXIT_FAILURE */ #define SUCCESS 1 #define FAILURE 0 struct e { int key; /* ... altri eventuali campi dato ... */ struct e *next; }; struct e *push (struct e *pTop, int val); struct e *pop (struct e *pTop, int *val, int *status); struct e *newE ( ); void traversal (struct e *pTop); void lettura (int *val); void stampa (int val, int status); int main ( void ) { char scelta[MAX_STR]; struct e *pTop; int val, status; pTop = NULL; do { printf ( "Effettua la scelta (push (p), pop (o), traversal (t), f (fine)): "); scanf ("%s", scelta); if (strcmp (scelta, "p") == 0){ lettura (&val); pTop = push (pTop, val); } else if (strcmp (scelta, "o") == 0){ pTop = pop (pTop,&val,&status); stampa (val, status); } else { -1-

description

Argomenti trattati: - gestione di uno stack con liste concatenate - queue con liste concatenate - liste concatenate ordinate

Transcript of Algoritmi e Programmazione Avanzata - Liste, pile, code

Page 1: Algoritmi e Programmazione Avanzata - Liste, pile, code

stack.c

/*

Algoritmi e Programmazione Avanzata

Tutore: Sergio Porcu

Argomento: stack

Gestione di uno stack con liste concatenate

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAX_STR 10

/* Utilizzo costanti locali invece di

EXIT_SUCCESS e EXIT_FAILURE */

#define SUCCESS 1

#define FAILURE 0

struct e {

int key;

/* ... altri eventuali campi dato ... */

struct e *next;

};

struct e *push (struct e *pTop, int val);

struct e *pop (struct e *pTop, int *val, int *status);

struct e *newE ( );

void traversal (struct e *pTop);

void lettura (int *val);

void stampa (int val, int status);

int

main (

void

)

{

char scelta[MAX_STR];

struct e *pTop;

int val, status;

pTop = NULL;

do {

printf (

"Effettua la scelta (push (p), pop (o), traversal (t), f (fine)): ");

scanf ("%s", scelta);

if (strcmp (scelta, "p") == 0) {

lettura (&val);

pTop = push (pTop, val);

} else

if (strcmp (scelta, "o") == 0) {

pTop = pop (pTop, &val, &status);

stampa (val, status);

} else {

-1-

Page 2: Algoritmi e Programmazione Avanzata - Liste, pile, code

stack.c

if (strcmp (scelta, "t") == 0) {

traversal (pTop);

} else {

if (strcmp (scelta, "f") != 0) {

printf ("Scelta errata!!!\n");

}

}

}

} while (strcmp (scelta, "f") != 0);

return (SUCCESS);

}

struct e *

push (

struct e *pTop,

int val

)

{

struct e *pNew;

pNew = newE ();

pNew->key = val;

pNew->next = pTop;

pTop = pNew;

return (pTop);

}

struct e *

pop (

struct e *pTop,

int *val,

int *status

)

{

struct e *pOld;

if (pTop != NULL) {

*status = SUCCESS;

*val = pTop->key;

pOld = pTop;

pTop = pTop->next;

free (pOld);

} else {

*status = FAILURE;

}

return (pTop);

}

void

traversal (

struct e *pTop

)

{

-2-

Page 3: Algoritmi e Programmazione Avanzata - Liste, pile, code

stack.c

struct e *pTmp;

fprintf (stdout, "pTop -> ");

pTmp = pTop;

while (pTmp != NULL) {

fprintf (stdout, "%d -> ", pTmp->key);

pTmp = pTmp->next;

}

fprintf (stdout, "NULL \n");

return;

}

struct e *

newE (

)

{

struct e *ePtr;

ePtr = (struct e *) malloc (sizeof (struct e));

if (ePtr==NULL) {

fprintf (stderr, "Allocazione fallita.");

exit (FAILURE);

}

return (ePtr);

}

/* lettura dati */

void

lettura (

int *val

)

{

fprintf (stdout, "Elemento da introdurre = ");

scanf ("%d", val);

return;

}

/* visualizzazione dati */

void

stampa (

int val,

int status

)

{

if (status == SUCCESS) {

fprintf (stdout, "Elemento estratto = %d\n", val);

} else {

fprintf (stdout, "Elemento inesistente.\n");

}

return;

}

-3-

Page 4: Algoritmi e Programmazione Avanzata - Liste, pile, code

stack.c

-4-

Page 5: Algoritmi e Programmazione Avanzata - Liste, pile, code

queue.c

/*

Algoritmi e Programmazione Avanzata

Tutore: Sergio Porcu

Argomento: queue

Queue con liste concatenate

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAX_STR 10

#define SUCCESS 2

#define FAILURE 3

struct e {

int key;

/* ... */

struct e *next;

};

struct e *enqueue (struct e *pTail, int val);

struct e *dequeue (struct e *pTail, int *val, int *status);

struct e *newE ( );

void traversal (struct e *pTail);

void lettura (int *val);

void stampa (int val, int status);

int

main (

void

)

{

char scelta[MAX_STR];

struct e *pTail;

int val, status;

pTail = NULL;

do {

printf (

"Effettua la scelta (enqueue (e), dequeue (d), traversal (t),"

" f (fine)): ");

scanf ("%s", scelta);

if (strcmp (scelta, "e") == 0) {

lettura (&val);

pTail = enqueue (pTail, val);

} else

if (strcmp (scelta, "d") == 0) {

pTail = dequeue (pTail, &val, &status);

stampa (val, status);

} else {

if (strcmp (scelta, "t") == 0) {

-1-

Page 6: Algoritmi e Programmazione Avanzata - Liste, pile, code

queue.c

traversal (pTail);

} else {

if (strcmp (scelta, "f") != 0) {

printf ("Scelta errata!!!\n");

}

}

}

} while (strcmp (scelta, "f") != 0);

return (SUCCESS);

}

struct e *

enqueue (

struct e *pTail,

int val

)

{

struct e *pNew;

pNew = newE ();

pNew->key = val;

/* campi */

if (pTail==NULL) {

pTail = pNew;

pTail->next = pTail;

} else {

pNew->next = pTail->next;

pTail->next = pNew;

pTail = pNew;

}

return (pTail);

}

struct e *

dequeue (

struct e *pTail,

int *val,

int *status

)

{

struct e *pOld;

if (pTail != NULL) {

*status = SUCCESS;

if (pTail == pTail->next) {

*val = pTail->key;

free (pTail);

pTail = NULL;

} else {

pOld = pTail->next;

*val = pOld->key;

pTail->next = pOld->next;

free (pOld);

-2-

Page 7: Algoritmi e Programmazione Avanzata - Liste, pile, code

queue.c

}

} else {

*status = FAILURE;

}

return (pTail);

}

void

traversal (

struct e *pTail

)

{

struct e *pTmp;

fprintf (stdout, "pTail -> ");

if (pTail == NULL) {

fprintf (stdout, "NULL\n");

} else {

pTmp = pTail;

do {

fprintf (stdout, "%d -> ", pTmp->key);

pTmp = pTmp->next;

} while (pTmp != pTail);

fprintf (stdout, "pTail \n");

}

return;

}

struct e *

newE (

)

{

struct e *p;

p = (struct e *) malloc (sizeof (struct e));

if (p==NULL) {

fprintf (stderr, "Allocazione fallita.");

exit (FAILURE);

}

return (p);

}

/* lettura dati */

void

lettura (

int *val

)

{

fprintf (stdout, "Elemento da introdurre = ");

scanf ("%d", val);

return;

-3-

Page 8: Algoritmi e Programmazione Avanzata - Liste, pile, code

queue.c

}

/* visualizzazione dati */

void

stampa (

int val,

int status

)

{

if (status == SUCCESS) {

fprintf (stdout, "Elemento estratto = %d\n", val);

} else {

fprintf (stdout, "Elemento inesistente.\n");

}

return;

}

-4-

Page 9: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfInt.c

/*

Algoritmi e Programmazione Avanzata

Tutore: Sergio Porcu

Argomento: liste concatenate ordinate

Gestione tramite menu e doppio puntatore. Dati i nteri.

*/

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

/************************************************** ******************

DEFINIZIONE DATI

*************************************************** *****************/

#define MAXC 30

#define SUCCESS 2

#define FAILURE 3

typedef int dato_t ;

typedef struct nodo {

dato_t val ;

struct nodo *punt ;

} nodo_t ;

/************************************************** ******************

PROTOTIPI

*************************************************** *****************/

/* Gestione Dati */

dato_t leggiDato (FILE *fp );

void stampaDato (FILE *fp , dato_t dato );

int precede (dato_t d1 , dato_t d2 );

int uguali (dato_t d1 , dato_t d2 );

/* Gestione Lista */

nodo_t *myAlloc (void );

nodo_t *creaListaVuota (void );

nodo_t *inserisci (nodo_t *hp, dato_t dato );

void stampaLista (FILE *fp , nodo_t *hp);

int cerca (nodo_t *hp, dato_t dato );

nodo_t *cancella (nodo_t *hp, dato_t dato );

nodo_t *leggiLista (FILE *fp );

/************************************************** ******************

GETIONE DATI

(sezione che puo' rendere il programma indipendent e dal tipo

di dati, e.g., funzionamento con stringhe di carat teri)

*************************************************** *****************/

dato_t

leggiDato (

FILE *fp

)

-1-

Page 10: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfInt.c

{

dato_t dato ;

/* Solo nel caso di fp==stdin visualizzo una richie sta-utente */

if (fp ==stdin ) {

fprintf (stdout , "Valore (intero): " );

}

fscanf (fp , "%d" , &dato );

return (dato );

}

void

stampaDato (

FILE *fp ,

dato_t dato

)

{

fprintf (fp , "%d\n" , dato );

return;

}

int

precede (

dato_t d1 ,

dato_t d2

)

{

if (d1 < d2)

return (1);

else

return (0);

}

int

uguali (

dato_t d1 ,

dato_t d2

)

{

if (d1 == d2)

return (1);

else

return (0);

}

/************************************************** ******************

GESTIONE LISTA

*************************************************** *****************/

nodo_t

*creaListaVuota (

void

)

{

-2-

Page 11: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfInt.c

return (NULL);

}

int

cerca (

nodo_t *hp,

dato_t dato

)

{

nodo_t *p;

for (p = hp; (p != NULL)&&(precede (p->val , dato )); p = p->punt );

if ((p != NULL)&&(uguali (p->val , dato )))

return (1);

else

return (0);

}

nodo_t

*cancella (

nodo_t *hp,

dato_t dato

)

{

nodo_t *p, *q0, *q1;

/* Lista vuota */

if (hp == NULL) {

fprintf (stderr , "ATTENZIONE: dato inesistente\n" );

return (hp);

}

/* Cancella in testa */

if (uguali (dato , hp->val )) {

p = hp->punt ;

free (hp);

return (p);

}

/* Cancella in mezzo o in coda. Percorrimento con d oppio puntatore:

q0 e q1 puntano a due nodi consecutivi, al mom ento dell'inserimento

q0 punta al nodo precedente, q1 al nodo da can cellare

*/

q0 = hp; q1 = hp->punt ;

/* cerca posizione - eventualmente fine lista (q1 = = NULL) */

while ((q1 != NULL)&&(precede (q1->val , dato ))) {

q0 = q1;

q1 = q1->punt ;

}

if ((q1 != NULL)&&(uguali (q1->val , dato ))) {

/* cancella */

q0->punt = q1->punt ;

free (q1);

}

else

fprintf (stderr , "ATTENZIONE: dato inesistente\n" );

-3-

Page 12: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfInt.c

/* hp non viene modificato */

return (hp);

}

nodo_t

*inserisci (

nodo_t *hp,

dato_t dato

)

{

nodo_t *p, *q0, *q1;

p = myAlloc ();

p->val = dato ;

/* Lista vuota */

if (hp == NULL) {

p->punt = NULL;

return (p);

}

/* Inserimento in testa */

if (precede (dato , hp->val )) {

p->punt = hp;

return (p);

}

/* Inserimento in mezzo o in coda. Percorrimento co n doppio puntatore:

q0 e q1 puntano a due nodi consecutivi, al mom ento dell'inserimento

q0 punta al nodo precedente, q1 al successivo

*/

q0 = hp; q1 = hp->punt ;

/* cerca posizione - eventualmente fine lista (q1 = = NULL) */

while ((q1 != NULL)&&(precede (q1->val , dato ))) {

q0 = q1;

q1 = q1->punt ;

}

/* inserisce */

q0->punt = p;

p->punt = q1;

/* hp non viene modificato */

return (hp);

}

void

stampaLista (

FILE *fp ,

nodo_t *hp

)

{

fprintf (stdout , "Lista:\n" );

while (hp != NULL) {

stampaDato (fp , hp->val );

hp = hp->punt ;

}

}

-4-

Page 13: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfInt.c

nodo_t

*leggiLista (

FILE *fp

)

{

nodo_t *p, *hp, *tp ;

dato_t d ;

hp = tp = NULL;

while (!feof (fp )) {

/* acquisisci dato */

d = leggiDato (fp );

p = myAlloc ();

p->val = d;

p->punt = NULL;

/* inserisci in coda */

if (tp == NULL)

hp = tp = p;

else {

tp ->punt = p;

tp = p;

}

}

return (hp);

}

nodo_t

*myAlloc (

void

)

{

nodo_t *p;

p = (nodo_t *) malloc (sizeof (nodo_t ));

if (p == NULL) {

fprintf (stderr , "ERRORE: memoria dinamica insufficiente\n" );

exit (1);

}

return (p);

}

/************************************************** ******************

MAIN

*************************************************** *****************/

int

main (

void

)

{

nodo_t *headp ;

-5-

Page 14: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfInt.c

dato_t d ;

int fine = 0;

char riga [MAXC];

FILE *fp ;

headp = creaListaVuota ();

while (!fine ) {

fprintf (stdout ,

"(I)ns/(R)ic/(C)anc/(V)isualizza/(S)alva/(L)eggi/(F )ine : " );

scanf ("%s" , riga );

switch (tolower (riga [0])) {

case 'c' :

d = leggiDato (stdin );

headp = cancella (headp , d);

break;

case 'f' :

fine = 1;

break;

case 'i' :

d = leggiDato (stdin );

headp = inserisci (headp , d);

break;

case 'l' :

fprintf (stdout , "Nome file: " );

scanf ("%s" , riga );

fp = fopen (riga , "r" );

if (fp == NULL) {

fprintf (stderr , "ERRORE in apertura di %s\n" , riga );

} else {

headp = leggiLista (fp );

}

break;

case 'r' :

d = leggiDato (stdin );

if (cerca (headp , d) == 1)

fprintf (stdout , "Trovato\n" );

else

fprintf (stdout , "Non trovato\n" );

break;

case 's' :

fprintf (stdout , "Nome file: " );

scanf ("%s" , riga );

fp = fopen (riga , "w" );

if (fp == NULL) {

fprintf (stderr , "ERRORE in apertura di %s\n" , riga );

}

else {

stampaLista (fp , headp );

fclose (fp );

}

break;

case 'v' :

stampaLista (stdout , headp );

break;

-6-

Page 15: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfInt.c

default:

fprintf (stderr , "Opzione sconosciuta\n" );

}

}

return (SUCCESS);

}

-7-

Page 16: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfString.c

/*

Algoritmi e Programmazione Avanzata

Tutore: Sergio Porcu

Argomento: liste concatenate ordinate

Gestione tramite menu e doppio puntatore.

Dati stringhe di caratteri.

Si osservi come questo programma sia stato

ottenuto dal programma

denominato listOfInt.c mediante modifica della

sola sezione "DATI" per modificare una lista

di interi in una di stringhe.

*/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <ctype.h>

/************************************************** ******************

DEFINIZIONE DATI

*************************************************** *****************/

#define MAXC 30

#define SUCCESS 2

#define FAILURE 3

typedef char * dato_t ;

typedef struct nodo {

dato_t val ;

struct nodo *punt ;

} nodo_t ;

/************************************************** ******************

PROTOTIPI

*************************************************** *****************/

/* Gestione Dati */

dato_t leggiDato (FILE *fp );

void stampaDato (FILE *fp , dato_t dato );

int precede (dato_t d1 , dato_t d2 );

int uguali (dato_t d1 , dato_t d2 );

/* Gestione Lista */

nodo_t *myAlloc (void );

nodo_t *creaListaVuota (void );

nodo_t *inserisci (nodo_t *hp, dato_t dato );

void stampaLista (FILE *fp , nodo_t *hp);

int cerca (nodo_t *hp, dato_t dato );

nodo_t *cancella (nodo_t *hp, dato_t dato );

nodo_t *leggiLista (FILE *fp );

/************************************************** ******************

GETIONE DATI

(sezione che puo' rendere il programma indipendent e dal tipo

-1-

Page 17: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfString.c

di dati, e.g., funzionamento con stringhe di carat teri)

*************************************************** *****************/

dato_t

leggiDato (

FILE *fp

)

{

char tmpDato [MAXC];

dato_t dato ;

/* Solo nel caso di fp==stdin visualizzo una richie sta-utente */

if (fp ==stdin ) {

fprintf (stdout , "Valore (stringa di caratteri): " );

}

fscanf (fp , "%s" , tmpDato );

dato = (char *) malloc ((strlen (tmpDato ) + 1) * sizeof (char ));

if (dato == NULL) {

fprintf (stderr , "ERRORE: memoria dinamica insufficiente.\n" );

exit (1);

}

strcpy (dato , tmpDato );

return (dato );

}

void

stampaDato (

FILE *fp ,

dato_t dato

)

{

fprintf (fp , "%s\n" , dato );

return;

}

int

precede (

dato_t d1 ,

dato_t d2

)

{

if (strcmp (d1, d2) < 0)

return (1);

else

return (0);

}

int

uguali (

dato_t d1 ,

dato_t d2

)

{

-2-

Page 18: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfString.c

if (strcmp (d1, d2) == 0)

return (1);

else

return (0);

}

/************************************************** ******************

GESTIONE LISTA

*************************************************** *****************/

nodo_t

*creaListaVuota (

void

)

{

return (NULL);

}

int

cerca (

nodo_t *hp,

dato_t dato

)

{

nodo_t *p;

for (p = hp; (p != NULL)&&(precede (p->val , dato )); p = p->punt );

if ((p != NULL)&&(uguali (p->val , dato )))

return (1);

else

return (0);

}

nodo_t

*cancella (

nodo_t *hp,

dato_t dato

)

{

nodo_t *p, *q0, *q1;

/* Lista vuota */

if (hp == NULL) {

fprintf (stderr , "ATTENZIONE: dato inesistente\n" );

return (hp);

}

/* Cancella in testa */

if (uguali (dato , hp->val )) {

p = hp->punt ;

free (hp);

return (p);

}

/* Cancella in mezzo o in coda. Percorrimento con d oppio puntatore:

q0 e q1 puntano a due nodi consecutivi, al mom ento dell'inserimento

q0 punta al nodo precedente, q1 al nodo da can cellare

-3-

Page 19: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfString.c

*/

q0 = hp; q1 = hp->punt ;

/* cerca posizione - eventualmente fine lista (q1 = = NULL) */

while ((q1 != NULL)&&(precede (q1->val , dato ))) {

q0 = q1;

q1 = q1->punt ;

}

if ((q1 != NULL)&&(uguali (q1->val , dato ))) {

/* cancella */

q0->punt = q1->punt ;

free (q1);

}

else

fprintf (stderr , "ATTENZIONE: dato inesistente\n" );

/* hp non viene modificato */

return (hp);

}

nodo_t

*inserisci (

nodo_t *hp,

dato_t dato

)

{

nodo_t *p, *q0, *q1;

p = myAlloc ();

p->val = dato ;

/* Lista vuota */

if (hp == NULL) {

p->punt = NULL;

return (p);

}

/* Inserimento in testa */

if (precede (dato , hp->val )) {

p->punt = hp;

return (p);

}

/* Inserimento in mezzo o in coda. Percorrimento co n doppio puntatore:

q0 e q1 puntano a due nodi consecutivi, al mom ento dell'inserimento

q0 punta al nodo precedente, q1 al successivo

*/

q0 = hp; q1 = hp->punt ;

/* cerca posizione - eventualmente fine lista (q1 = = NULL) */

while ((q1 != NULL)&&(precede (q1->val , dato ))) {

q0 = q1;

q1 = q1->punt ;

}

/* inserisce */

q0->punt = p;

p->punt = q1;

/* hp non viene modificato */

return (hp);

}

-4-

Page 20: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfString.c

void

stampaLista (

FILE *fp ,

nodo_t *hp

)

{

fprintf (stdout , "Lista:\n" );

while (hp != NULL) {

stampaDato (fp , hp->val );

hp = hp->punt ;

}

}

nodo_t

*leggiLista (

FILE *fp

)

{

nodo_t *p, *hp, *tp ;

dato_t d ;

hp = tp = NULL;

while (!feof (fp )) {

/* acquisisci dato */

d = leggiDato (fp );

p = myAlloc ();

p->val = d;

p->punt = NULL;

/* inserisci in coda */

if (tp == NULL)

hp = tp = p;

else {

tp ->punt = p;

tp = p;

}

}

return (hp);

}

nodo_t

*myAlloc (

void

)

{

nodo_t *p;

p = (nodo_t *) malloc (sizeof (nodo_t ));

if (p == NULL) {

fprintf (stderr , "ERRORE: memoria dinamica insufficiente\n" );

exit (1);

-5-

Page 21: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfString.c

}

return (p);

}

/************************************************** ******************

MAIN

*************************************************** *****************/

int

main (

void

)

{

nodo_t *headp ;

dato_t d ;

int fine = 0;

char riga [MAXC];

FILE *fp ;

headp = creaListaVuota ();

while (!fine ) {

fprintf (stdout ,

"(I)ns/(R)ic/(C)anc/(V)isualizza/(S)alva/(L)eggi/(F )ine : " );

scanf ("%s" , riga );

switch (tolower (riga [0])) {

case 'c' :

d = leggiDato (stdin );

headp = cancella (headp , d);

break;

case 'f' :

fine = 1;

break;

case 'i' :

d = leggiDato (stdin );

headp = inserisci (headp , d);

break;

case 'l' :

fprintf (stdout , "Nome file: " );

scanf ("%s" , riga );

fp = fopen (riga , "r" );

if (fp == NULL) {

fprintf (stderr , "ERRORE in apertura di %s\n" , riga );

} else {

headp = leggiLista (fp );

}

break;

case 'r' :

d = leggiDato (stdin );

if (cerca (headp , d) == 1)

fprintf (stdout , "Trovato\n" );

else

fprintf (stdout , "Non trovato\n" );

break;

-6-

Page 22: Algoritmi e Programmazione Avanzata - Liste, pile, code

listOfString.c

case 's' :

fprintf (stdout , "Nome file: " );

scanf ("%s" , riga );

fp = fopen (riga , "w" );

if (fp == NULL) {

fprintf (stderr , "ERRORE in apertura di %s\n" , riga );

}

else {

stampaLista (fp , headp );

fclose (fp );

}

break;

case 'v' :

stampaLista (stdout , headp );

break;

default:

fprintf (stderr , "Opzione sconosciuta\n" );

}

}

return (SUCCESS);

}

-7-