Quicksort e qsort() Alessio Orlandi. 28 marzo 2010

Documenti analoghi
L accesso ai dispositivi esterni (tastiera, monitor, file,...) viene gestito mediante canali di comunicazione.

4 GLI ARRAY E LE STRINGHE

Programmazione. Cognome... Nome... Matricola... Prova scritta del 22 settembre Negli esercizi proposti si utilizzano le seguenti classi:

Linguaggio C: introduzione

Breve riepilogo della puntata precedente:

ESAME DI FONDAMENTI DI INFORMATICA I ESAME DI ELEMENTI DI INFORMATICA. 28 Gennaio 1999 PROVA SCRITTA

ESAME DI FONDAMENTI DI INFORMATICA I ESAME DI ELEMENTI DI INFORMATICA. 28 Gennaio 1999 PROVA SCRITTA

Esercitazione 4. Comandi iterativi for, while, do-while

APPELLO SCRITTO DI PROGRAMMAZIONE 1 CORSO DI LAUREA IN MATEMATICA UNIVERSITÀ DEGLI STUDI DI MILANO VI.2014

Definizione di metodi in Java

Fondamenti di Informatica. Algoritmi di Ricerca e di Ordinamento

Esercitazione 5. Procedure e Funzioni Il comando condizionale: switch

Problema: calcolare il massimo tra K numeri

Somma di numeri floating point. Algoritmi di moltiplicazione e divisione per numeri interi

Linguaggio C++ 8. Matrici

Array multidimensionali e stringhe

Il generatore di numeri casuali

Programmazione. Cognome... Nome... Matricola... Prova scritta del 11 luglio 2014

Gestione di files Motivazioni

IL CONCETTO DI FILE. È illecito operare oltre la fine del file.

Individuazione di sottoproblemi

Input/output in C e in C++

Codice Gray. (versione Marzo 2007)

Files in C++ Fondamenti di Informatica. R. Basili. a.a

Shell BASH. Variabili Redirezione

La gestione dei caratteri in C

Laboratorio di Programmazione Appunti sulla lezione 4: Divide et impera e algoritmi di ordinamento

Strutture Dinamiche. Fondamenti di Informatica

Laboratorio di Algoritmi e Strutture Dati II Semestre 2005/2006. Ordinamenti: mergesort e quicksort

Lab. di Sistemi Operativi - Esercitazione - Comandi Shell

06AZN - Fondamenti di Informatica (GES, LOP, ORG) Esercitazione di laboratorio n. 8 (1/12/09)

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1

Unità Didattica 3 Linguaggio C. Generalità sulle Funzioni. Variabili locali e globali. Passaggio di parametri per valore.

Gli array. Gli array. Gli array. Classi di memorizzazione per array. Inizializzazione esplicita degli array. Array e puntatori

Funzioni in C. Violetta Lonati

Laboratorio di Informatica

TOP DOWN. Compiti in classe proposti Modulo 1 JUVENILIA SCUOLA. Iacobelli Ajme Marrone

DOCUMENTAZIONE WEB RAIN - ACCESSO CLIENTI

IEIM Esercitazione IX Ordinamento vettori e Struct Complesse. Alessandro A. Nacci -

Mini-Corso di Informatica

TEOREMA DEL RESTO E REGOLA DI RUFFINI

Corso di Fondamenti di Informatica

Consideriamo un vettore allocato dinamicamente

giapresente( ) leggi( ) char * strstr(char * cs, char * ct) NULL

FILE BINARI FILE BINARI

Laboratorio di Programmazione: Linguaggio C Lezione 9 del 27 novembre 2013

UNIVERSITÀ DEGLI STUDI DI PAVIA FACOLTÀ DI INGEGNERIA. Matlab: esempi ed esercizi

STRINGHE: ARRAY DI CARATTERI! a p e \0

Esercizio 1. Esercizio 2

ESERCIZIO 1 (Definizione funzioni passaggio parametri per copia)

VBA è un linguaggio di scripting derivato da Visual Basic, da cui prende il nome. Come ogni linguaggio ha le sue regole.

Informatica B

Fondamenti di Programmazione

Anno 2. Risoluzione di sistemi di primo grado in due incognite

Lab. di Sistemi Operativi - Esercitazione n 2 - a.a. 2012/2013

Gestione dei file. Linguaggio ANSI C Input/Output - 13

2) FILE BINARI: è una sequenza di byte avente una corrispondenza uno a uno con la sequenza ricevuta dal dispositivo esterno.

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

Manipolazioni elementari di flussi di testo strutturati

Introduzione al C. Stream e disk file

Matematica - SMID : Programmazione Febbraio 2009 FOGLIO RISPOSTE

Organizzare la scuola inclusiva

Corso di Fondamenti di Informatica Classi di istruzioni 2

ESERCITAZIONE MICROECONOMIA (CORSO B) ESEMPI DI ESERCIZI DI TEORIA DEI GIOCHI

La Rappresentazione dell Informazione

= < < < < < Matematica 1

Allocazione Dinamica della Memoria

Stringhe di caratteri

CAPITOLO V. DATABASE: Il modello relazionale

Esercizi per il recupero del debito formativo:

Java Native Interface Appunti

Laboratorio di Programmazione Lezione 1. Cristian Del Fabbro

Matlab 5. Funzioni. Slide basate sul corso di C. Blundo. A.A. 2010/ GPersiano. Laboratorio di Informatica per Fisici 1

7 Disegni sperimentali ad un solo fattore. Giulio Vidotto Raffaele Cioffi

Divide et impera. Divide et impera. Divide et impera. Divide et impera

Esame Informatica Generale 13/04/2016 Tema A

La rappresentazione delle informazioni

4 Le liste collegate 4.0. Le liste collegate. 4 Le liste collegate Rappresentazione di liste 4.1 Rappresentazione di liste

Questo paragrafo e quello successivo trattano gli stessi argomenti del capitolo B6 relativo alla soluzione grafica dei sistemi di primo grado.

Guida a SacramentiWeb 1.2

public BankAccount() { balance = 0; } public BankAccount(double initialbalance) { balance = initialbalance; }

Lettura e scrittura di file di dati input/output

Uso di metodi statici. Walter Didimo

Introduzione al Linguaggio C

Fondamenti di Informatica T1 Mappe

Operazioni di Ordinamento

ADT Coda con priorità

Corso di Programmazione a oggetti

Alberi binari di ricerca

Modulo 2 Data Base - Modello Relazionale

Variabili. Unità 2. Domenico Daniele Bloisi. Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER

Introduzione al C. Introduzione. Linguaggio ad alto livello. Struttura di un programma C

Lab 11 Gestione file di testo"

Heap e code di priorità

Informatica per la Comunicazione/ Verdicchio/ 19/06/2013/ Domande / Versione 1

Le variabili. Olga Scotti

3. Terza esercitazione autoguidata: progetto gestione voli

I puntatori e l allocazione dinamica di memoria

Informatica B. Sezione D. Scuola di Ingegneria Industriale Laurea in Ingegneria Energetica Laurea in Ingegneria Meccanica

public double getlato() restituisce la lunghezza del lato del quadrato che esegue il metodo.

Transcript:

Quicksort e qsort() Alessio Orlandi 28 marzo 2010

Intro Quicksort è l algoritmo di ordinamento più implementato, insieme con Mergesort. Tutte le librerie standard UNIX ne prevedono una implementazione. Sono quasi sempre ricorsive e scelgono il pivot come mediano tra tre posizioni casuali (randomized median-of-three). Purtroppo, non sono stabili. Trattandosi di ordinamento per confronto sono funzioni generiche.

Quicksort: ripasso Quicksort: distribuisci rispetto ad un pivot, ricorri sulle due metà. void d i s t r i b ( i n t A, i n t sx, i n t dx, i n t px ) { i f ( px!= dx ) scambia (A, px, dx ) ; i = sx ; j = dx 1 ; while ( i < j ) { while ( i < j && A[ i ] <= A[ dx ] ) i ++; while ( i < j && A[ j ] >= A[ dx ] ) j ; i f ( i < j ) scambia ( A, i, j ) ; } i f ( i!= dx ) scambia ( A, i, dx ) ; return i ; } In parole: trova la prima coppia di discrepanze (da sx e da dx), scambia e riparti.

Quicksort per confronti La procedura appena descritta richiede 2 confronti: e delle chiamate a scambia. E se volessimo ordinare stringhe? A[i] A[dx] e A[j] A[dx]

Quicksort per confronti La procedura appena descritta richiede 2 confronti: A[i] A[dx] e A[j] A[dx] e delle chiamate a scambia. E se volessimo ordinare stringhe? Dovremmo cambiare il significato di e, e (dentro scambia) =. Ordinamento per confronti è astraibile dalla tipizzazione. Scopo delle prossime slide: arrivarci.

Quicksort astratto 1 Generalizzazione con confrontatori: i n t comp ( TIPO a, TIPO b ) ; restituisce 1 se a > b, 0 se a = b, +1, se a < b. Sostituiamo A[i] < A[dx] con comp(a[i], A[dx]) == 1 e simili. Implementazione a carico dell utilizzatore 2 Spostamento di aree di memoria: s = s i z e o f (TIPO ) ; memcpy ( ( byte )A + i s, ( byte )A + j s, s ) ;

Puntatori void * Supponiamo di confrontare fornendo i puntatori agli elementi. Se ordino interi: int comp ( int *a, int *b ) Se ordino reali: int comp ( float *a, float *b ) Se ordino stringhe: int comp ( char **a, char ** b ) Mettiamoci nei panni di chi scrive la procedura di quicksort. Come chiamare comp correttamente? Se sbaglio tipo?

Puntatori void * Supponiamo di confrontare fornendo i puntatori agli elementi. Se ordino interi: int comp ( int *a, int *b ) Se ordino reali: int comp ( float *a, float *b ) Se ordino stringhe: int comp ( char **a, char ** b ) Mettiamoci nei panni di chi scrive la procedura di quicksort. Come chiamare comp correttamente? Se sbaglio tipo? Bisogna ricorrere a dei puntatori generici: void *.

Puntatori void * - II void * è un puntatore che non ha significato se non dopo un cast: non può essere dereferenziato. Non si può accedere ad un array void *. E permesso convertire tramite casting i puntatori void * in qualsiasi altro tipo di puntatore: void c a l l ( void a, void b ) { i n t y1 = ( i n t ) a ; i n t y2 = ( i n t ) b ;... }.. i n t x = m a l l o c ( s i z e o f ( i n t ) 1 0 2 4 ) ; void a = ( void )& x ; c a l l ( x, a ) ;

Dilemma risolto: i n t comp ( void a, void b ) ; Scriviamo quicksort parlando di una generica comp, sarà chi la implementa a converitre i puntatori al tipo corretto. Quindi il nostro prototipo di quicksort potrebbe essere così: void q u i c k s o r t ( void A, i n t n, i n t dim ) ; A: array del tipo generico da ordinare. n: numero di elementi nell array. dim: memcpy richiede la dimensione del tipo. sizeof(...). L utilizzatore crea comp e chiama quicksort.

Esempio di chiamata void q u i c k s o r t ( void A, i n t n, i n t dim ) ; i n t a r r a y = m a l l o c ( s i z e o f ( i n t ) n ) ; f o r ( i = 0 ; i < n ; i++ ) a r r a y [ i ] = rand ()%100; q u i c k s o r t ( a r r a y, n, s i z e o f ( i n t ) ) ;

Puntatori a funzione Ora supponiamo di voler fare quicksort due volte nel nostro programma, una volta su interi, una volta di stringhe. Come usare due confrontatori diversi? La soluzione sarebbe aggiungere un parametro: la funzione di confronto da usare. Tramite puntatori a funzione.

Puntatori a funzione Ora supponiamo di voler fare quicksort due volte nel nostro programma, una volta su interi, una volta di stringhe. Come usare due confrontatori diversi? La soluzione sarebbe aggiungere un parametro: la funzione di confronto da usare. Tramite puntatori a funzione. Scrittura di quicksort: void q u i c k s o r t (..., i n t ( compar ) ( void, void )){... compar ( a, b ) ; } Utilizzo: i n t mio comp ( void a, void b ) { return 1; } q u i c k s o r t (..., mio comp,... ) ;

Puntatori a funzione - II Ogni segnatura di funzione definisce un tipo a se: tipo di ritorno, del primo argomento, etc.. Una funzione con input int e restituisce void è del tipo ( void ) ( ) ( int, i n t ) Dandogli un nome (notare le tonde intorno all asterisco!) ( void ) ( nome ) ( int, i n t ) Chiunque voglia usare un puntatore a funzione compatibile, deve implementare una funzione che abbia esattamente la stessa segnatura: restituisce void, un solo parametro int. La funzione si passa tramite il suo nome (e avviene per riferimento).

Uso di qsort() Il linguaggio C mette a disposizione una implementazione di quicksort: void q s o r t ( void A, i n t n, i n t dim, i n t ( compar ) ( const void, const void ) ) ; A: array da ordinare. n: numero di elementi nell array dim: dimensione di un elemento dell array (sizeof) compar: funzione di comparazione a cui vengono passati puntatori ad oggetti dell array.

void qsort(void *A, int n, int dim, int (*cmp)(const void*, const void * ) ; Un esempio: i n t fcomp ( const void a, const void b ) { f l o a t x = ( ( f l o a t ) a ) ; f l o a t y = ( ( f l o a t ) b ) ; i f ( x < y ) return 1 ; i f ( x > y ) return 1; return 0 ; }... f l o a t x ; // a r r a y g i a pronto i n t n ; // d i m e n s i o n e d e l l a r r a y q s o r t ( x, n, s i z e o f ( f l o a t ), fcomp ) ;

Esercizio 1 Scrivere un programma che legga da tastiera un array A di stringhe e che utilizzi la funzione di libreria qsort per ordinare in ordine alfabetico crescente le stringhe in input. Stampare in outupt la sequenza di stringhe ordinata, una per riga. Linput è formattato nel seguente modo: sulla prima riga si trova il numero N di stringhe. Seguono N righe contenenti ognuna una una stringa dellinsieme da ordinare. Le stringhe contengono soltanto carat- teri alfanumerici (a - z minuscoli e maiuscoli o numeri, nessuno spazio o punteggiatura) e sono lunghe al più 1000 caratteri ciascuna.

Esercizio 2 Scrivere un programma che utilizzi la procedura qsort e ordini un vettore di interi non negativi (in input), in modo da ottenere il seguente effetto. Larray riordinato deve contenere prima tutti i numeri pari e, a seguire, i numeri dispari. I numeri pari devono essere ordinati in modo crescente fra di loro. I numeri dispari devono essere ordinati in modo decrescente fra di loro. La sequenza in input e, come al solito, il numero N (non limitato) di interi seguiti da N valori interi non negativi. Stampare la sequenza riordinata in output su una sola riga. Nota: il numero zero e, per convenzione, ritenuto sempre pari.

Esercizio 3 Risolvere il tema di esame del 28/05/2009 (ignorando le modalità di consegna). Il testo (e relativa soluzione da guardare DOPO) sono disponibili all indirizzo http://www.cli.di.unipi.it/doku/lib/exe/fetch.php/ informatica/all-a/all09/lab20090528.zip

Esercizio 4 Scrivere un programma che implementi la ricerca binaria (dicotomica) su un insieme di stringhe in input. Linput fornito e formato da una prima riga contenente N il numero di stringhe tra cui effettuare la ricerca. Le successive N righe contengono stringhe ordinate in modo alfabetico crescente. Segue una sequenza di dimensione non conosciuta di coppie di righe. La prima riga di ogni coppia e il valore 1 o 0. Se il valore e 0 il programma termina (non ci sono piu richieste). Se il valore e 1, sulla riga successiva trovate la stringa da cercare. Per tanto linput contiene le N + 1 righe dellinsieme e ogni successiva richiesta di ricerca viene preceduta da una riga con il numero 1. La procedura termina quando si trova uno 0. Le stringhe contengono solo caratteri alfanumerici e non sono piu lunghe di 1000 caratteri. Loutput e composto da una riga per ognuna delle richieste. Ogni riga contiene il risultato della ricerca binaria: se lelemento appare nellinsieme, stamparne la posizione (valore da 0 a N 1). Altrimenti, stampare -1.