Algoritmi e Programmazione Avanzata - Liste, pile, code
-
Upload
sergio-porcu -
Category
Education
-
view
178 -
download
3
description
Transcript of 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-
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-
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-
stack.c
-4-
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-
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-
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-
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-
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-
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-
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-
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-
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-
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-
listOfInt.c
default:
fprintf (stderr , "Opzione sconosciuta\n" );
}
}
return (SUCCESS);
}
-7-
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-
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-
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-
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-
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-
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-
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-