Modello dati LISTA LISTA: LISTA: sequenza finita di 0 o più elementi LISTA di tipo T: lista in cui tutti gli elementi sono dello stesso tipo T. es. lista.

Slides:



Advertisements
Presentazioni simili
Puntatori Linguaggio C.
Advertisements

1 Le s-espressioni. 2 Un nuovo esempio completo: le s-espressioni Sexpr 4 alberi binari (possibilmente vuoti) che hanno sulle foglie atomi (stringhe)
1 Progettazione gerarchica delle s- espressioni, utilizzando lereditarietà
PROGETTO MODULO B – a.a Possono scegliere questo progetto solo gli studenti che hanno superato la prova del progetto di intercorso. Siano dati.
Tipi di dato astratti Lista, Pila, Coda, Albero.
Strutture dati lineari
Alcune Classi Standard Object, Vettori. Esercizio dellultima volta Superclasse Persona Sottoclasse Libro.
Esercizio 2. Mostrare l'evoluzione dello stato (ambiente di classi, heap, pila, System.out) durante la valutazione delle seguenti dichiarazioni di classe.
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Lez. 91 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Alberi di ricerca.
Strutture dati elementari
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Esercizi su alberi binari
Tail recursion: esempio
Mergesort1 if (n>1) /* la collezione contiene almeno due elementi. */ {1. Dividi la collezione in due di circa la metà degli elementi. 2. chiamata ricorsiva.
Alberi binari Definizione della struttura dati: struct tree { };
Sezione: Costruttori Costruttori. Definizione dei costruttori Se per una classe A non scrivo nessun costruttore, il sistema automaticamente crea il costruttore.
// PROTOTIPI void costruisciLista(Pnodo &, string &); void stampaLista(Pnodo ); void creaNodo (int, Pnodo&); Pnodo inserisciNodoTesta (int,Pnodo &); Pnodo.
1 Ultima Lezione del Corso di Fondamenti di Informatica 1 a.a – 06 Ma 29-Nov-2005.
1. Conoscere luso delle collezioni in Java Comprendere le principali caratteristiche nelle varie classi di Collection disponibili Saper individuare quali.
JAVA C import java.util.*; #include <stdio.h>
1 Esercitazione sui segnali Problema: creare un programma analizzatore di file testuali che prenda come argomenti il nome di un file e una sequenza di.
Modello dati LISTA LISTA: LISTA: sequenza finita di 0 o più elementi LISTA di tipo T: lista in cui tutti gli elementi sono dello stesso tipo T. es. lista.
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
1 Implementazione di Linguaggi 2 PARTE 6 Implementazione di Linguaggi 2 PARTE 6 Massimo Ancona DISI Università di Genova Testo: A.V. Aho, R. Sethi, J.D.Ullman.
Esercizi su pile Scrivere una funzione che restituisca una nuova pila che contiene i valori di una pila in ingresso in ordine inverso. La pila originale.
Esercizi su alberi binari
2000 Prentice Hall, Inc. All rights reserved. 1 Capitolo 6: Classi e astrazione dati 1.Introduzione 2.Definizione delle strutture 3.Accedere ai membri.
Sottoprogrammi e Unità di Compilazione Nicola Fanizzi Laboratorio - Corso di Programmazione (B) C.d.L. in Informatica DIB - Università degli Studi di Bari.
Array Ricerca Ordinamento Fusione Nicola Fanizzi Laboratorio - Corso di Programmazione (B) C.d.L. in Informatica DIB - Università degli Studi di Bari.
1 Strutture Dinamiche Corso di Informatica A Vito Perrone.
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
Le liste dinamiche La ricorsione
Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),
Sequence. CREARE UNA SEQUENCE CREATE SEQUENCE nome [INCREMENT BY n] [START WITH n] [MAXVALUE n | NOMAXVALUE] [MINVALUE n | NOMINVALUE] [CYCLE | NOCYCLE]
AN Fondam98 Puntatori Azioni e procedure Assegnamenti, indirizzi e puntatori.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Ricerca di una chiave: Search(x, k) if x == nil or k == x.key return x
Piero Scotto - C141 C14 #14 Puntatori e file. Il problema dellordinamento. Debug.
22 maggio 2002 Avvisi: Ultima lezione: mercoledì 29 maggio II Esonero: mercoledì 5 giugno, ore 10:00.
1.Scrivere una funzione per cercare un numero x in una lista circolare di interi. La funzione deve restituire NULL se il numero non esiste. 2.Scrivere.
Corso di informatica Athena – Periti Informatici
(1) Sistemi Operativi Prof. P. Cattaneo ufficio: L Ricevimento: Martedì14.00 –
24 aprile 2002 Avvisi: Risultati 1 o Esonero: (entro) lunedi 27 disponibili nella pag. WEB, ma anche esposti nella bacheca fuori dal corridoio 2 o dente,
Multiset. Progettare (specifica con identificazione delle eventuali astrazioni necessarie, incluse eccezioni, e implementazione) del tipo di dato Multiset,
Esercizi Liste.
2000 Prentice Hall, Inc. All rights reserved. I file Apertura e chiusura I file ad accesso sequenziale I file ad accesso casuale Apre un file già esistente.
Grafi Rappresentazione mediante liste di adiacenza:
Tail recursion: esempio
Esercizi su alberi binari di ricerca
Collection & Generics in Java
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 5 Le strutture informative Corso di Informatica 2 a.a. 2003/04 Lezione 5.
Esercitazioni su liste
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
AlgoLab - Pile e Code Pile e code Laboratorio di Algoritmi 02/03 Prof. Ugo de’ Liguoro.
CORSO DI PROGRAMMAZIONE II
13. Strutture dati dinamiche Ing. Simona Colucci Informatica - CDL in Ingegneria Industriale- A.A
Divide et Impera Quicksort Mergesort Charles Antony Richard Hoare
Alberi n-ary Lezioni di C.
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
comprensione e modifica di codice
APPUNTI SUL LINGUAGGIO C Implementazioni di Liste Concatenate
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C Allocazione dinamica della memoria
APPUNTI SUL LINGUAGGIO C Alberi Binari – primi esercizi
concetti ed applicazioni
Ese 3 (del 3 Aprile 2003).
Transcript della presentazione:

Modello dati LISTA LISTA: LISTA: sequenza finita di 0 o più elementi LISTA di tipo T: lista in cui tutti gli elementi sono dello stesso tipo T. es. lista di int, di real, di struct,… es. lista di int, di real, di struct,… Lista che contiene elementi a 1,…,a n (a 1,…,a n ) Es. lista dei numeri primi <20 in ordine crescente (1,2,3,5,7,11,13,17) (1,2,3,5,7,11,13,17)

Modello dati LISTA LISTA: LISTA: sequenza finita di 0 o più elementi LISTA di tipo T: lista in cui tutti gli elementi sono dello stesso tipo T. es. lista di int, di real, di struct,… es. lista di int, di real, di struct,… Lista che contiene elementi a 1,…,a n (a 1,…,a n ) Es. lista dei numeri primi <20 in ordine crescente (1,2,3,5,7,11,13,17) (1,2,3,5,7,11,13,17) Lunghezza di una lista = numero di elementi nella lista Es. lunghezza di (1,2,3,5,7,11,13,17) è 8 Lista vuota = = lista con zero elementi

Modello dati LISTA Data la lista (a 1,…,a n ) Head= primo elemento della lista = a 1 Head= primo elemento della lista = a 1 Tail= lista senza head = (a 2,…,a n ) Tail= lista senza head = (a 2,…,a n )

Modello dati LISTA Data la lista (a 1,…,a n ) Head= primo elemento della lista = a 1 Head= primo elemento della lista = a 1 Tail= lista senza head = (a 2,…,a n ) Tail= lista senza head = (a 2,…,a n ) Sottolista: ogni lista (ai,ai+1,…, aj) 1<i<j<n Sottolista : ogni lista (ai,ai+1,…, aj) 1<i<j<n Sottosequenza: elimina alcuni elementi dalla lista lascandi gli altri in ordine lascandi gli altri in ordine Es. Data (1,2,3) sottoliste:, (1), (2), (3), (1,2), (2,3), (1,2,3) sottoliste:, (1), (2), (3), (1,2), (2,3), (1,2,3) sottosequenze: tutte le sottoliste e (1,3). sottosequenze: tutte le sottoliste e (1,3).

Modello dati LISTA Data la lista (a 1,…,a n ) Prefisso= sottolista che inizia con a 1 Prefisso= sottolista che inizia con a 1 Suffisso= sottolista che finisce con an La lista vuota è prefisso e suffisso di ogni lista Es. Data (1,2,3,4) prefissi: (1), (1,2), (1,2,3), (1,2,3,4) prefissi: (1), (1,2), (1,2,3), (1,2,3,4) suffissi: (4), (3,4), (2,3,4), (1,2,3,4) suffissi: (4), (3,4), (2,3,4), (1,2,3,4)

Modello dati LISTA Data la lista (a 1,…,a n ) Elemento in posizione i= ai Predecessore di ai = ai-1 Successore di ai= ai+1 Occorrenza di x = una posizione i tale che ai=x Es. Data (a,b,c,b,b) elemento in posizione 1 = a elemento in posizione 1 = a elemento in posizione 4 = b elemento in posizione 4 = b occorrenza di a = 1 occorrenza di a = 1 occorrenze di b = 2,4,5 occorrenze di b = 2,4,5 occorrenza di c = 3 occorrenza di c = 3

Operazioni su liste Sorting: data la lista (a 1,…a n ) restituisce la lista ordinata (b 1,…,b n ) contenente gli stessi elementi Merging: date due liste ordinate restituisce una lista ordinata contenente tutti gli elementi delle liste input Dizionario: insieme di elementi su cui si vogliono fare le operazioni di inserzione, ricerca e cancellazione

Operazioni su liste Push: insert nuovo elemento come head della lista es. L=(1,2,3,2), push(L,1) L=(1,1,2,3,2) es. L=(1,2,3,2), push(L,1) L=(1,1,2,3,2) Pop: cancella head della lista es. L=(1,2,3,2), pop(L) L=(2,3,2) es. L=(1,2,3,2), pop(L) L=(2,3,2) Concatenazione di 2 liste: L=(a1,…,an), M=(b1,…bm) (a1,…,an,b1,…bm) L=(a1,…,an), M=(b1,…bm) (a1,…,an,b1,…bm)

Liste a puntatori (struttura dati) typedef struct CELL *LIST struct CELL{ struct CELL{ int element; /*per semplicità assumiamo elementi interi*/ int element; /*per semplicità assumiamo elementi interi*/ LIST next} LIST next} lista: (modello) L=(a1,…,an) lista: (modello) L=(a1,…,an) (sruttura) a1 a2 an / (sruttura) a1 a2 an /

Liste a puntatori (struttura dati) Dizionario su lista a puntatori (insert, delete, lookup) Nota: dizionario contiene ogni elemento al più una volta ordine non ha importanza, (1,3,5) equiv. (3,1,5) Lookup: è x in D? Metodo: Scorre celle della lista L che rappresenta D finchè trova x oppure L finisce Boolean lookup(int x, LIST L) {if (L==NULL) return false else if(L->element==x) return true else return lookup(x, list ->next)}

Liste a puntatori (struttura dati) Boolean lookup(int x, LIST L) {if (L==NULL) return false else if(L->element==x) return true else return lookup(x, list ->next)} R.T. T(0)=c T(n)=b+T(n-1) T(n)=O(n)

Liste a puntatori (struttura dati) Boolean lookup(int x, LIST L) {if (L==NULL) return false else if(L->element==x) return true else return lookup(x, list ->next)} Correttezza. Mostriamo per induzione S(n): lookup(.) su una lista di n elementi restituisce true se e solo se x in L

Liste a puntatori (struttura dati) Boolean lookup(int x, LIST L) {if (L==NULL) return false else if(L->element==x) return true else return lookup(list ->next)} Correttezza. Mostriamo per induzione S(n): lookup(.) su una lista di n elementi restituisce true se e solo se x in L Base: n=0. n=0 L=NULL; risultato false; ok. Passo: Sia S(n-1) vera. Consideriamo lista di n elementi. Lookup(L) restituisce vero se x è il primo elemento di L, ok!, altrimenti restituisce vero sse (per i.i.) x è in tail di L; ok!.

Liste a puntatori (struttura dati) Cancellazione di x da lista L: Elimina la cella contenente x Void delete(int x, LIST *pL) {if (*pL!=NULL) if(*pL->element==x) *pL=*pL ->next else delete(x, * pL->next)} x x S i usa il puntatore pL (chiamata per referenza) invece di L per poter modificare L.

Liste a puntatori (struttura dati) Cancellazione di x da lista L: Elimina la cella contenente x Void delete(int x, LIST *pL) {if (*pL!=NULL) if(*pL->element==x) *pL=*pL ->next else delete(x, * pL->next)} x x R.T. T(n)=O(n) Correttezza. Mostrare per induzione S(n): delete(L) su una lista di n elementi restituisce L se x non in L, elimina x da L altrimenti. S i usa il puntatore pL (chiamata per referenza) invece di L per poter modificare L.

Liste a puntatori (struttura dati) Inserzione di x nella lista L: Inserisce, se x non in L, una cella contenente x Void insert(int x, LIST *pL) {if (*pL==NULL) {/*inserisci x */ (*pl)=(LIST)malloc(sizeof(struct CELL)); (*pL)->element=x; (*pl)->next=NULL;} else if((*pL)->element!=x) insert(x,(*pL) ->next)}

Liste a puntatori (struttura dati) Inserzione di x nella lista L: Inserisce, se x non in L, una cella contenente x Void insert(int x, LIST *pL) {if (*pL==NULL) {/*inserisci x */ (*pl)=(LIST)malloc(sizeof(struct CELL)); (*pL)->element=x; (*pl)->next=NULL;} else if((*pL)->element!=x) insert(x,(*pL) ->next)} Se la lista è vuota crea cella contenente x L X /

Liste a puntatori (struttura dati) Inserzione di x nella lista L: Inserisce, se x non in L, una cella contenente x Void insert(int x, LIST *pL) {if (*pL==NULL) {/*inserisci x */ (*pl)=(LIST)malloc(sizeof(struct CELL)); (*pL)->element=x; (*pl)->next=NULL;} else if((*pL)->element!=x) insert(x,(*pL) ->next)} Se la lista è vuota crea cella contenente x L Altrimenti arriva a fine lista: NULL X /

Liste a doppi puntatori type def struct CELL *LIST Struct CELL {LIST previous; int element; LIST next} Es. Cancella la cella puntata dal puntatore p: delete(LIST p, LIST *pL) L / a1a2an /

Liste a doppi puntatori Es. Cancella la cella puntata dal puntatore p Void delete(LIST p, LIST *pL) {if (p->next != NULL) p->next->previous=p->previous; if (p->previous==NULL) (*pL)=p->next; else p->previous->next=p->next;} p

Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…), (SPLIT) 2. Ordina le due liste separatamente (MERGESORT) 3. Fondi le due liste ottenute (ordinate) in una unica lista ordinata (MERGE)

MERGE (di due liste ordinate L 1,L 2 M) Algoritmo dipende dalla rappresentazione delle liste Usiamo LISTE A PUNTATORI: ogni elemento della lista è una struttura typedef struct CELL *LIST struct CELL{ int element /* elemento della lista*/ LIST next /* puntatore alla successiva struttura (elemento)*/ } (a 1,a 2,…,a n ) a 1 a 2 … a n

MERGE (di due liste ordinate L 1,L 2 M) -Trova il minimo tra il primo elemento di L1 e di L2, rimuovilo dalla lista di appartenenza ed aggiungilo ad M. - Ripeti LIST merge ( LIST list1, LIST list2) { if (list1== NULL ) return list2 else if ( list2== NULL) return list1 else if (list1->element element) /* entrambe le liste non vuote ed il primo elemento di list1 è minore del primo di list2*/ { list1->next=merge(list1->next, list2); return list1; } else /*entrambe le liste non vuote ed il primo elemento di list2 è minore del primo di list1*/ { list2->next=merge(list1, list2->next); return list2; }

MERGE (di due liste ordinate L 1,L 2 M) LIST merge (LIST list1, LIST list2) { if (list1==NULL) return list2 else if ( list2== NULL) return list1 else if ( list1->element element ) {/* entrambe le liste non vuote ed il primo elemento di list1 è minore del primo di list2*/ list1->next=merge(list1->next, list2); return list1;} else …} list1 a 1 a 2 … a n list2 b 1 b 2 … b n a 2 … a n list1 a 1 merge b 1 … b n

MERGE (di due liste ordinate L 1,L 2 M) list list list1 merge(list1, list2) merge (2-4-7, )

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, )

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) merge(, ) merge(4-7, 5-6-9)

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) merge(, ) merge(4-7, 5-6-9) merge(, ) merge(7, 5-6-9)

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) merge(, ) merge(4-7, 5-6-9) merge(, ) merge(7, 5-6-9) merge(, ) merge(7, 6-9)

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) merge(, ) merge(4-7, 5-6-9) = merge(, ) merge(7, 5-6-9) = merge(, ) merge(7, 6-9) = merge(, ) merge(7, 9)

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) = merge(, ) merge(4-7, 5-6-9) = merge(, ) merge(7, 5-6-9) = merge(, ) merge(7, 6-9) = merge(, ) merge(7, 9) = merge(NULL, )= merge(, 9) 9

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) = merge(, ) merge(4-7, 5-6-9) = merge(, ) merge(7, 5-6-9) = merge(, ) merge(7, 6-9) = merge(, ) = merge(7, 9) 7

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) = merge(, ) merge(4-7, 5-6-9) = merge(, ) merge(7, 5-6-9) = merge(, )= merge(7, 6-9) 6

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) = merge(, ) merge(4-7, 5-6-9) = merge(, ) = merge(7, 5-6-9) 5

MERGE (di due liste ordinate L 1,L 2 M) list list Merge(list1, list2) merge (2-4-7, ) merge( list2) merge(4-7, ) = merge(, ) = merge(4-7, 5-6-9) 4

MERGE (di due liste ordinate L 1,L 2 M) list list list1=merge(list1, list2) merge (2-4-7, ) merge( list2)=list2 merge(4-7, ) list2 3

MERGE (di due liste ordinate L 1,L 2 M) list list list1=merge(list1, list2) merge (2-4-7, ) list1 2

SPLIT (di L in due liste ordinate L 1,L 2 ) LIST Split (LIST list) { List pSecondcell; if (list==NULL) return NULL else if (list->next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell; } L=(a 1,a 2, a 3, a 4, …, a n ) L 1 =(a 1, a 3, …), L 2 =(a 2, a 4, …)

SPLIT (di L in due liste ordinate L1,L2) LIST Split (LIST list) { List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}} list a 1 a 2 a 3 … a n

SPLIT (di L in due liste ordinate L1,L2) LIST Split (LIST list) { List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}} list a 1 a 2 a 3 … a n pSecondcell

SPLIT (di L in due liste ordinate L1,L2) LIST Split (LIST list) { List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}} list a 1 a 2 a 3 … a n pSecondcell

SPLIT (di L in due liste ordinate L1,L2) LIST Split (LIST list) { List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}} list a 1 a 2 a 3 … a n Split di pSecondcell

MERGESORT BASE: Se la lista contiene 0 o 1 elemento, stop Ind.: Split di (a 1,a 2, …) in (a 1,a 3,…) e (a 2,a 4,…) Mergesort delle due liste separatamente Merge delle 2 liste ordinate

MERGESORT LIST Mergesort (LIST list) { List SecondList; if (list==NULL) return NULL else if (list->next==NULL) return list else {/* list contiene almeno 2 elementi (da ordinare)*/ SecondList=split(list); return merge(mergesort(list),mergesort(ScondList)); } BASE: Se la lista contiene 0 o 1 elemento, stop Ind.: Split di (a 1,a 2, …) in (a 1,a 3,…) e (a 2,a 4,…) Mergesort delle due liste separatamente Merge delle 2 liste ordinate

R.T. della funzione SPLIT LIST Split (LIST list) { List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}} Sia n=|list|. Si ha la relazione di ricorrenza T(0)=T(1)=O(1) T(n)=c+T(n-2), per n>1 Quindi T(n)=O(n)

R.T. del MERGE LIST merge ( LIST list1, LIST list2) { if (list1== NULL ) return list2 else if ( list2== NULL) return list1 else if (list1->element element) { list1->next=merge(list1->next, list2); return list1; } else { list2->next=merge(list1, list2->next); return list2;} } Siano n1=|list1|, n2=|list2|, n=n1+n2. Si ha la relazione di ricorrenza T(0)=T(1)=O(1) (almeno 1 lista vuota) T(n)=c+T(n-1), per n>1 Quindi T(n)=O(n)

R.T. MERGESORT LIST Mergesort (LIST list) {List SecondList; if (list==NULL) return NULL else if (list->next==NULL) return list else /* list contiene almeno 2 elementi (da ordinare)*/ {SecondList=split(list); return merge(mergesort(list),mergesort(ScondList));} } Sia n=|list|. Si ha la relazione di ricorrenza T(0)=T(1)=O(1) (list contiene 0 o 1 elemento) T(n)=O(n) + O(n) +T(n/2) +T(n/2) =O(n) + 2 T(n/2), per n>1 Quindi T(n)=O(n log n)

R.T. MERGESORT T(0)=T(1)=O(1) T(n)=c n + 2 T(n/2), per n>1 Si assuma per semplicità che n=2 m (cioè m=log n)

R.T. MERGESORT T(0)=T(1)=O(1) T(n)=c n + 2 T(n/2), per n>1 Si assuma per semplicità che n=2 m (cioè m=log n) T(2 m )=c 2 m + 2 T(2 m-1 ) =c 2 m + 2 (c 2 m T(2 m-2 ))= c 2 m + c 2 m +4 T(2 m-2 ) = 2c 2 m + 4 T(2 m-2 )

R.T. MERGESORT T(0)=T(1)=O(1) T(n)=c n + 2 T(n/2), per n>1 Si assuma per semplicità che n=2 m (cioè m=log n) T(2 m )=c 2 m + 2 T(2 m-1 ) =c 2 m + 2 (c 2 m T(2 m-2 ))= c 2 m + c 2 m +4 T(2 m-2 ) = 2c 2 m + 4 T(2 m-2 ) = 2c 2 m +4 (c 2 m T(2 m-3 ))=2c 2 m + c 2 m +8T(2 m-3 ) = 3c 2 m + 8 T(2 m-3 )

R.T. MERGESORT T(0)=T(1)=O(1) T(n)=c n + 2 T(n/2), per n>1 Si assuma per semplicità che n=2 m (cioè m=log n) T(2 m )=c 2 m + 2 T(2 m-1 ) =c 2 m + 2 (c 2 m T(2 m-2 ))= c 2 m + c 2 m +4 T(2 m-2 ) = 2c 2 m + 4 T(2 m-2 ) = 2c 2 m +4 (c 2 m T(2 m-3 ))=2c 2 m + c 2 m +8T(2 m-3 ) = 3c 2 m + 8 T(2 m-3 ) …… = i c 2 m + 2 i T(2 m-i )

R.T. MERGESORT T(0)=T(1)=O(1) T(n)=c n + 2 T(n/2), per n>1 Si assuma per semplicità che n=2 m (cioè m=log n) T(2 m )=c 2 m + 2 T(2 m-1 ) =c 2 m + 2 (c 2 m T(2 m-2 ))= c 2 m + c 2 m +4 T(2 m-2 ) = 2c 2 m + 4 T(2 m-2 ) = 2c 2 m +4 (c 2 m T(2 m-3 ))=2c 2 m + c 2 m +8T(2 m-3 ) = 3c 2 m + 8 T(2 m-3 ) …… = i c 2 m + 2 i T(2 m-i ) Scegliendo i=m=log n si ha T(n)= T(2 m ) = m c 2 m + 2 m T(2 0 )= m c n + n a= = c n log n + a n = O(n log n)

Correttezza MERGESORT LIST Mergesort (LIST list) {List SecondList; if (list==NULL) return NULL else if (list->next==NULL) return list else /* list contiene almeno 2 elementi (da ordinare)*/ {SecondList=split(list); return merge(mergesort(list),mergesort(ScondList));} } Assumiamo correttezza delle funz. split e merge (esercizio) Per induzione completa su n=|list|. Base. Se n=0 o n=1, restituisce lista inalterata, ok.

Correttezza MERGESORT LIST Mergesort (LIST list) {List SecondList; if (list==NULL) return NULL else if (list->next==NULL) return list else /* list contiene almeno 2 elementi (da ordinare)*/ {SecondList=split(list); return merge(mergesort(list),mergesort(ScondList));} } Assumiamo correttezza delle funz.split e merge (esercizio) Per induzione completa su n=|list|. Base. Se n=0 o n=1, restituisce lista inalterata, ok. Passo (n>1). Assumiamo per i.i. mergesort(list), mergesort(ScondList) restituiscono liste input ordinate.

Correttezza MERGESORT LIST Mergesort (LIST list) {List SecondList; if (list==NULL) return NULL else if (list->next==NULL) return list else /* list contiene almeno 2 elementi (da ordinare)*/ {SecondList=split(list); return merge(mergesort(list),mergesort(ScondList));} } Assumiamo correttezza delle funz.split e merge (esercizio) Per induzione completa su n=|list|. Base. Se n=0 o n=1, restituisce lista inalterata, ok. Passo (n>1). Assumiamo per i.i. mergesort(list), mergesort(ScondList) restituiscono liste input ordinate. Quindi Split divide n elementi lista input tra list e Secondlist; mergesort(list),mergesort(ScondList) ordina le liste; Merge fonde le liste restituendo in output una lista ordinata contenete gli stessi n elementi della lista input.

Liste mediante array Struttura dati: array per contenere elementi variabile length per contare # elementi Array A[0..MAX-1] (lista può contenere al più MAX el.) Lista (a 0,…,a n-1 ) usa prime n locazioni di A, length=n 0 1 n-1 MAX a0a0 a n-1 … … Typedef struct LIST /*lista struttura con 2 campi: array e length*/ { int A[MAX]; int length; }

Liste mediante array 0 1 n-1 MAX a0a0 a n-1 … … Typedef struct LIST /*lista struttura con 2 campi: array e length*/ { int A[MAX]; int length; } pL: puntatore a struct LIST L pL->A[i] = elemento i-mo della lista pL->length = lunghezza lista

Liste mediante array pL: puntatore a struct LIST pL->A[i]= elemento i-mo della lista pL->length=lunghezza lista LOOKUP Ricerca lineare Boolean lookup(int x, LIST *pL) {int i for (i=0, i length,i++) if (x==*pL->A[i]) return TRUE; return FALSE;} R.T O(n), n=lunghezza lista

Liste mediante array Ricerca lineare con sentinella Boolean lookup(int x, LIST *pL) {int i; pL->A[pl->length]=x; /*sentinella*/ i=0; while (x!=pL->A[i]) i++; return (i length);} R.T O(n), n=lunghezza lista

Liste mediante array Ricerca lineare con sentinella Boolean lookup(int x, LIST *pL) {int i; *pL->A[*pL->length]=x; /*sentinella*/ i=0; while (x!=*pL->A[i]) i++; return (i length);} R.T O(n), n=lunghezza lista NOTA: numero di operazioni minore rispetto alla ricerca lineare. Boolean lookup(int x, LIST *pL) {int i for (i=0, i length,i++) if (x==*pL->A[i]) return TRUE; return false;}

LOOKUP con RICERCA BINARIA su lista ORDINATA Sia a 0,a 1,…,a n-1 una lista ordinata (a 0 < a 1 < …< a n-1 ) rappresentata mediante un array A[0..n-1]. Cerchiamo x. a0a0 a n-1 a mid mid= [(n-1)/2] Se x<A[mid] continua la ricerca di x in A[0.. mid-1] Se x>A[mid] continua la ricerca di x in A[mid+1.. n-1] Se x=A[mid], trovato x, STOP

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Boolean BinSesarch(int x, int A[],int low, int high) {int mid; if (low > high) return FALSE; /*low>high array vuoto*/ else { mid=(low+high)/2; if(x<A[mid]) return BinSearch(x,A,low,mid-1); else if (x>A[mid]) return BinSearch(x,A,mid+1,high); else return TRUE /*x=A[mid]*/

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Boolean BinSesarch(int x, int A[],int low, int high) {int mid; if (low > high) return FALSE; else { mid=(low+high)/2; if(x<A[mid]) return BinSearch(x,A,low,mid-1); else if (x>A[mid]) return BinSearch(x,A,mid+1,high); else return TRUE /*x=A[mid]*/ CORRETTEZZA: restituisce true sse x in A[low..high] Per induzione completa su m=high-low+1 (ampiezza array) Base. m=0 (high<low), array vuoto, restituisce False, ok Passo. (esercizio)

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Sia P(k)=max numero elementi su cui si può fare la ricerca con k confronti (chiamate ricorsive) P(1)=1 P(2)=3 (mid, P(1)=1 elementi minori di mid, P(1)=1 elementi maggiori di mid)

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Sia P(k)=max numero elementi su cui si può fare la ricerca con k confronti (chiamare ricorsive) P(1)=1 P(2)=3 (mid, P(1)=1 elementi minori di mid, P(1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1 (mid, P(k-1)=1 elementi minori di mid, P(k-1)=1 elementi maggiori di mid)

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Sia P(k)=max numero elementi su cui si può fare la ricerca con k confronti (chiamate ricorsive) P(1)=1 P(2)=3 (mid, P(1)=1 elementi minori di mid, P(1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1 (mid, P(k-1)=1 elementi minori di mid, P(k-1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1= 2( 2 P(k-2)+1)+1= 4 P(k-2)+2+1=

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Sia P(k)=max numero elementi su cui si può fare la ricerca con k confronti (chiamate ricorsive) P(1)=1 P(2)=3 (mid, P(1)=1 elementi minori di mid, P(1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1 (mid, P(k-1)=1 elementi minori di mid, P(k-1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1= 2( 2 P(k-2)+1)+1= 4 P(k-2)+2+1= … = 2 i P(k-i) +2 i-1 +…

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Sia P(k)=max numero elementi su cui si può fare la ricerca con k confronti (chiamate ricorsive) P(1)=1 P(2)=3 (mid, P(1)=1 elementi minori di mid, P(1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1 (mid, P(k-1)=1 elementi minori di mid, P(k-1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1= 2( 2 P(k-2)+1)+1= 4 P(k-2)+2+1= … = 2 i P(k-i) +2 i-1 +… = 2 i P(k-i) + 2 i -1 = 2 k-1 P(1) + 2 k-1 -1 = 2 k -1

LOOKUP con RICERCA BINARIA su lista ORDINATA a low a high a mid Sia P(k)=max numero elementi su cui si può fare la ricerca con k confronti (chiamate ricorsive) P(1)=1 P(2)=3 (mid, P(1)=1 elementi minori di mid, P(1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1 (mid, P(k-1)=1 elementi minori di mid, P(k-1)=1 elementi maggiori di mid) P(k)=2 P(k-1)+1= 2( 2 P(k-2)+1)+1= 4 P(k-2)+2+1= … = 2 i P(k-i) +2 i-1 +… = 2 i P(k-i) + 2 i -1 = 2 k-1 P(1) + 2 k-1 -1 = 2 k -1 k Quindi ponendo n= P(k) si ha n=2 k -1 k= log (n+1) numero confronti=R.T=O(log n)

CODE CODA: struttura basata sulle liste, ma con restrizioni sulle operazioni di inserzione e cancellazione Inserzione: sempre da un estremo detto rear Cancellazione: sempre da altro estremo, detto front FIFO: First In First Out (a 0, a 1, …, a n-1 ) front rear Es. C=(a,b,c) insert d in C C=(a,b,c,d) delete C=(b,c,d)

OPERAZIONI su CODA Q clear(Q): rendi Q vuota dequeue(Q,x): se Q è vuota return FALSE, altrimenti - poni x=elemento alfront di Q - elimina elemento al front di Q - return TRUE enqueue(Q,x): se Q è piena return FALSE, altrimenti - inserisci x al rear di Q - return TRUE isempty(Q): restituisci TRUE se Q è vuota, FALSE alt. isfull(Q): restituisci TRUE se Q è piena, FALSE alt.

CODE mediante Liste a Puntatori Coda lista con due puntatori: front e rear typedef struct{ LIST front, rear } QUEUE Coda piena mai, isfull(Q) restituisce sempre FALSE Coda vuota front=NULL BOOLEAN isEmpty(QUEUE *pQ) {return (pQ->front=NULL);} void clear(QUEUE *pQ) {*pQ->front=NULL;} front rear /

CODE mediante Liste a Puntatori BOOLEAN dequeue(QUEUE *pQ, int *px) {if (isempty(pQ) return FALSE; else {(*px)=pQ->front->element; pQ->front=pQ->front->next; return TRUE;} front rear / a

CODE mediante Liste a Puntatori BOOLEAN dequeue(QUEUE *pQ, int *px) {if (isempty(pQ) return FALSE; else {(*px)=pQ->front->element; pQ->front=pQ->front->next; return TRUE;} front rear / a x vale a

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;}

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;} front

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;} front rear

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;} front rear / x

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;} front rear /

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;} front rear

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;} front rear

CODE mediante Liste a Puntatori BOOLEAN enqueue(QUEUE *pQ, int x) {if (isempty(pQ) {pQ->front=(LIST)malloc(sizeof(struct CELL)); pQ->rear= pQ->front;} else {pQ->rear->next= =(LIST)malloc(sizeof(struct CELL)); pQ->rear=pQ->rear->next;} pQ->rear->element=x; pQ->rear->next=NULL; return TRUE;} front rear X / Nota. Il R.T. è O(1) per tutte le operazioni

CODE mediante ARRAY Array circolare: immaginato come se dopo la posizione n-1 venga nuovamente la posizione 0 A= … 0 n-1 Visto comeIn senso orario n … Typedef struct{ int A[n]; int front, rear} QUEUE Front, rear: le posizioni occupate dalla coda vanno da front a rear, front precede rear in senso orario

CODE mediante ARRAY Front, rear: le posizioni occupate dalla coda vanno da front a rear, front precede rear in senso orario Front=2, rear=5 coda=(A[2],A[3],A[4],A[5]) Front=5, rear=2 coda=(A[5],…,A[8],A[0],A[1],A[2])

CODE mediante ARRAY Front, rear: le posizioni occupate dalla coda vanno da front a rear, front precede rear in senso orario Coda vuota: front in posizione immediatamente successiva al rear es. front=3, rear=2.

CODE mediante ARRAY Front, rear: le posizioni occupate dalla coda vanno da front a rear, front precede rear in senso orario Coda vuota: front in posizione immediatamente successiva al rear es. front=3, rear=2. Coda piena: contiene n-1 elementi front a 2 posizioni successive al rear es. front=3, rear=1 coda =(A[3],…,A[n-1],A[0],A[1]) Nota: se coda contenesse n elementi allora front in posizione immediatamente successiva al rear, es. front=3, rear=2 coda=(A[3],…,A[n-1], A[0], A[1], A[2]), si confonderebbe con coda vuota

CODE mediante ARRAY Operazioni modulo n: x+y mod n=resto divisine di (x+y) per n es. x+1 mod n= x+1 se x<n-1, 0 se x=n-1. Clear: poni front=1, rear=0 (quindi front=rear+1 mod n) isEmpty: controlla se front=rear+1 mod n isFull: risultato del confronto (front==rear +2 % n) Enqueue(Q,x): se coda è piena restituisce FALSE, altrimenti rear=(rear +1)%n; Q[rear]=x; return TRUE Dequeue(Q,x): se coda vuota restituisce FALSE, altrimenti x=Q[front]; front=(front+1)%n; return TRUE

CODE mediante ARRAY 8 0=rear 1=front In una coda circolare con n=9, inizialmente vuota: Inserire 5 Inserire 2 1=front=rear 5 1=front 5 2=rear 2

CODE mediante ARRAY Inserire 6 Cancellare 1=front 5 2=rear 2 1=front 5 3=rear 2 6 2=front 3=rear 2 6

STACK (o Pile) Stack. lista (a 1,…,a n ) su cui vogliamo fare 2 operazioni principali: PUSH, POP. Tutte le operazioni principali sono fatte ad uni stesso estremo detto TOP Se stack=S= (a 1,…,a n ), assumiamo top=ultimo elemento=a n PUSH(x,S): inserisce x al top (a 1,…,a n,x) POP(S): elimina elemento al top (a 1,…,a n-1 ) Stack=Struttura LIFO (Last In First Out)

STACK (o Pile) Es. Compilatore usa espressioni aritmetiche tradotte da notazione infissa a postfissa (operandi precedono operatore) (3+4)*2 34+2* 3*5+2*7 35*27*+

STACK (o Pile) Es. Compilatore usa espressioni aritmetiche tradotte da notazione infissa a postfissa (operandi precedono operatore) (3+4)*2 34+2* Espressioni postfisse valutate mediante stack Simbolo Azione Stack 3 push push 4 3,4 + pop, pop push push 2 7,2 * pop, pop push 14 14

STACK (o Pile) 3*5+2*7 35*27*+ Simbolo Azione Stack 3 push push 5 3,5 * pop, pop push push 2 15,2 7 push 7 15,2,7 * pop, pop 15 push 14 15,14 + pop, pop push 28 28

Operazioni su STACK Clear(S): rende stack S vuoto IsEmpty(S): TRUE se S vuoto, FALSE altrimenti IsFull(S): TRUE se S pieno, FALSE altrimenti Pop(S,x): se S è vuoto, restituisce FALSE altrimenti pone x=elemento al top di S e restituisce TRUE Push(S,x): se S è pieno, restituisce FALSE altrimenti inserisce x al top di S e restituisce TRUE

stack mediante array Primo elemento inserito è a 0 Ultimo elemento inserito è a n-1 top=n-1 Stack vuoto top= n-1 MAX-1 a0a0 a n-1 … … Typedef struct LIST /*lista struttura con 2 campi: array e top*/ { int A[MAX]; int top; } STACK Top Stack (a 0,…,a n-1 ) usa prime n locazioni di A, length=n

stack mediante array Passiamo stack per referenza, altrimenti si copia intero array Void clear(STACK *pS) { ps->top=-1} Boolean isEmpty(STACK *pS) { return (ps->top<0) } Boolean isFull(STACK *pS) { return (ps->top<= MAX-1) }

stack mediante array Boolean Pop(STACK *pS, int *px) { if isempty(pS)) return FALSE else { (*px)=ps->A[(ps->top)--]; return TRUE } } Boolean Push(STACK *pS, int x) { if isFull(pS)) return FALSE else { ps->A[++(ps->top)]=x; return TRUE } }

Stack mediante Liste a Puntatori Stack lista a puntatori con top al front typedef struct CELL *STACK struct CELL { int element; STACK next} S / top

Stack mediante Liste a Puntatori Stack pieno mai, isFull restituisce sempre FALSE BOOLEAN isFull(STACK *pS) {return FALSE} Stack vuoto lista vuota BOOLEAN isEmpty(QUEUE *pS) {return (*pS)==NULL);} void clear(QUEUE *pQ) {(*pS)=NULL;} S / top

Stack mediante Liste a Puntatori BOOLEAN pop(STACK *pS, int *px) {if ((*pS)==NULL) return FALSE; else { (*px)=(*ps)->element; (*ps)=(*ps)->next; return TRUE } } top S / S /

Stack mediante Liste a Puntatori BOOLEAN push(STACK *pS, int *px) {STACK newcell; newcell=(STACK)malloc(sizeof(struct CELL)); newcell->element=x; newcell->next=(*pS); (*pS)=newcell; return TRUE } } top S / S /x

Implementazione di Chiamate di funzioni mediante Stack Quando funzione F chiama P: l esecuzione di F è sospesa e le variabili di F sono memorizzate Per funzioni ricorsive si hanno piu chiamate attive allo Stesso tempo della stessa funzione int fact(int n) {if (n<=1) return 1 else return n*fact(n-1)} fact(10) fact(9) fact(8) … fact(2) sono tutte attive (e sospese) fino al completamento di fact(1). Ogni chiamata attiva ha diversi valori di: input, variabili, …

Implementazione di Chiamate di funzioni mediante Stack Esecuzione di funzione è chiamata attivazione Record di attivazione: tutti i dati relativi allesecuzione; es: variabili locali, da dove riprendere esecuzione,… STACK = record di attivazione di tutte le attivazioni non terminate A1A1 … Top A2A2 A3A3 AkAk A 1 in esecuzione A 2 ha chiamato A 1, riprende al termine di A 1 A 3 ha chiamato A 2, riprende al termine di A 2 …

Implementazione di Chiamate di funzioni mediante Stack Es. Record di attivazione per fact (n,fact) (valore input, valore output (riempito alla fine)) fact(4) crea stack (4, fact) chiama fact(3) stack Chiama fact(2) stack (3, fact ) (4, fact ) (3, fact ) (4, fact ) (2, fact )

Implementazione di Chiamate di funzioni mediante Stack Chiama fact(2) stack Chiama fact(1) stack (3, fact ) (4, fact ) (2, fact ) (3, fact ) (4, fact ) (2, fact ) (1, fact)

Implementazione di Chiamate di funzioni mediante Stack Fact(1) termina Fact(2) termina (3, fact ) (4, fact ) (2, fact ) (1, fact=1) (3, fact ) (4, fact ) (2, fact ) (3, fact ) (4, fact ) (2, fact =2) (3, fact ) (4, fact )

Implementazione di Chiamate di funzioni mediante Stack Fact(2) termina Fact(3) termina Fact(4) termina (3, fact ) (4, fact ) (2, fact =2) (3, fact ) (4, fact ) (3, fact =6) (4, fact ) (4, fact ) (4, fact=24 )