Linguaggio Java e Algoritmi ( 09CBIPC, 09CBIMQ ) Corsi di Laurea in Ingegneria del cinema e dei mezzi di comunicazione Matematica per l’Ingegneria Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 1 Java language • Originally developed by James Gosling at Sun Microsystems and released in 1995 • It derives much of its syntax from C and C++ • Java applications are typically compiled to bytecode that can run on any Java Virtual Machine (JVM) regardless of computer architecture • As of May 2007 Sun relicensed most of its Java technologies under the GNU General Public License • Sun Microsystems was acquired by Oracle Corporation's in 2010 • Java is as of 2012 one of the most popular programming languages in use, particularly for client-server web applications, with a reported 10 million users • Google and Android, Inc. have chosen to use Java to design applications for the Android operating system, an open-source operating system built on the Linux 2.6 kernel, designed primarily for touchscreen mobile devices (smartphones, tablet PCs, mobile Internet devices, …) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 2 Java Environment • Java bytecodes • platform-independent intermediate language • Java Virtual Machine (Java VM) • virtual machine able to execute Java bytecodes Java source Java bytecodes Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 3 Java Portability • any implementation of Java VM can execute Java bytecodes Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 4 Java Security Check of correctness of parameter types and compliance with access rules Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 5 Java Platform • Java Application Programming Interface (Java API) • set of Java bytecodes libraries (packages) supporting a large range of functionalities • http://docs.oracle.com/javase/7/docs/api/index.html Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 6 Java Technology CDC = Connected Device Configuration CLDC = Connected Limited Device Configuration PDA = Personal Digital Assistant (palmare) POS = Point Of Sale Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 7 Java Platform - Standard Edition Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 8 Java Development Kit (JDK) Tools • javac • • The compiler for the Java programming language. java • • The launcher for Java applications. javadoc • • API documentation generator. appletviewer • • Run and debug applets without a web browser. jar • • jdb • • C header and stub generator. Used to write native methods. javap • • The Java Debugger. javah • • Manage Java Archive (JAR) files. Class file disassembler extcheck • Utility to detect Jar conflicts. Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 9 Java: HelloWorld program HelloWorld.java public class HelloWorld { /* The HelloWorld class implements an application that displays "Hello World!" to the standard output */ public static void main ( String[] args ) { System.out.println( "Hello World!" ); } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 10 Eclipse Integrated Development Environment (IDE) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 11 Java: Primitive Data Types Keyword Description Size/Format (integers) byte Byte-length integer 8-bit two's complement short Short integer 16-bit two's complement int Integer 32-bit two's complement Long integer 64-bit two's complement Literal Data type 178 int 8864L long long 37.266 double (real numbers) 37.266D double 87.363F float float Single-precision floating point 26.77e3 double double Double-precision floating point 64-bit IEEE 754 ' c' char (other types) true boolean char A single character false boolean boolean A boolean value (true or false) true or false (real numbers) 32-bit IEEE 754 (other types) 16-bit Unicode character Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 12 Java: Arithmetic Operators Operator Use Description + op1 + op2 Adds op1 and op2 * op1 - op2 op1 * op2 Subtracts op2 from op1 Multiplies op1 by op2 / op1 / op2 Divides op1 by op2 % op1 % op2 Computes the remainder of dividing op1 by op2 Operator Use Description ++ op++ Increments op by 1; evaluates to the value of op before it was incremented ++ ++op Increments op by 1; evaluates to the value of op after it was incremented -- op-- Decrements op by 1; evaluates to the value of op before it was decremented -- --op Decrements op by 1; evaluates to the value of op after it was decremented Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 13 Java: Relational and Conditional Operators Operator Use Returns true if > >= < <= == != op1 > op2 op1 >= op2 op1 < op2 op1 <= op2 op1 == op2 op1 != op2 op1 is greater than op2 op1 is greater than or equal to op2 op1 is less than op2 op1 is less than or equal to op2 op1 and op2 are equal op1 and op2 are not equal Operator Use Returns true if && op1 && op2 op1 and op2 are both true , conditionally evaluates op2 || either op1 or op2 is true , conditionally evaluates op2 & op1 || op2 ! op op1 & op2 | op1 | op2 either op1 or op2 is true , always evaluates op1 and op2 ^ op1 ^ op2 if op1 and op2 are different--that is if one or the other of the operands is true but not both ! op is false op1 and op2 are both true , always evaluates op1 and op2 Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 14 Java: Shift and Logical Operators Operator Use Operation >> op1 >> op2 shift bits of op1 right by distance op2 << op1 << op2 shift bits of op1 left by distance op2 >>> op1 >>> op2 shift bits of op1 right by distance op2 (unsigned) Operator Use Operation & op1 & op2 bitwise and | op1 | op2 bitwise or ^ op1 ^ op2 bitwise xor ~ ~op2 bitwise complement Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 15 Java: Assignment Operators op1= op2; Operator Use Equivalent to += op1 += op2 op1 = op1 + op2 -= op1 -= op2 op1 = op1 - op2 *= op1 *= op2 op1 = op1 * op2 /= op1 /= op2 op1 = op1 / op2 %= op1 %= op2 op1 = op1 % op2 &= op1 &= op2 op1 = op1 & op2 |= op1 |= op2 op1 = op1 | op2 ^= op1 ^= op2 op1 = op1 ^ op2 <<= op1 <<= op2 op1 = op1 << op2 >>= op1 >>= op2 op1 = op1 >> op2 >>>= op1 >>>= op2 op1 = op1 >>> op2 Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 16 Java: Other Operators Operator Use Description ?: op1 ? op2 : op3 If op1 is true, returns op2. Otherwise, returns op3. [] type [ ] Declares an array of unknown length, which contains type elements. [] type [ op1 ] [] op1[ op2 ] . op1.op2 () op1(params) (type) (type) op1 new new op1 instanceof op1 instanceof op2 Returns true if op1 is an instance of op2 Creates and array with op1 elements. Must be used with the new operator. Accesses the element at op2 index within the array op1. Indices begin at 0 and extend through the length of the array minus one. Is a reference to the op2 member of op1. Declares or calls the method named op1 with the specified parameters. The list of parameters can be an empty list. The list is comma-separated. Casts (converts) op1 to type . An exception will be thrown if the type of op1 is incompatible with type. Creates a new object or array. op1 is either a call to a constructor, or an array specification. Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 17 Java: Control Flow Statements - looping while (boolean expression) { } statement(s) do { statement(s) } while (boolean expression); for (initialization ; termination ; increment ) { } statement(s) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 18 Java: Control Flow Statements – decision making if (boolean expression) { } statement(s) switch (expression) { case constant expression : statement(s) ... ... default: if (boolean expression) { } else { } statement(s) statement(s) } break; statement(s) break; Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 19 Java: Control Flow Statements – branching label: someJavaStatement ; break; terminates the innermost switch , for , while , or do-while statement break label; terminates an outer switch , for , while , or do-while statement with the given label continue; terminates the current iteration of the innermost loop continue label; terminates the current iteration of the loop with the given label return; terminates the current method return value; terminates the current method and returns a value to the method's caller Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 20 Java: Creating Arrays Declaring a Variable to Refer to an Array int[] anArray; // declare an array of integers float[] anArrayOfFloats; boolean[] anArrayOfBooleans; Object[] anArrayOfObjects; String[] anArrayOfStrings; Creating an Array anArray = new int[10]; // create an array of 10 integers Declaring, Creating and Initializing an Array boolean[] answers = { true, false, true, true, false }; Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 21 Java: Using Arrays Accessing an Array Element Getting the Size of an Array anArray[i] arrayname.length Copying Arrays System.arraycopy (Object source, int srcIndex, Object dest, int destIndex, int length) source Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 22 Java: Iterating through Arrays (for statement) Iterating through Arrays class ForDemo { public static void main(String[] args) { int[] numbers = {1,2,3,4,5,6,7,8,9,10}; for (int i=0 ; i<numbers.length ; i++) System.out.print(" " + numbers[i]); } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 23 Java: Iterating through Arrays (enhanced for statement) Iterating through Arrays class EnhancedForDemo { public static void main(String[] args) { int[] numbers = {1,2,3,4,5,6,7,8,9,10}; for (int item : numbers) System.out.print(" " + item); } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 24 Software Quality Functionality Usability Performance Software Quality to perform the requirements and specification to be user friendly to provide appropriate response and processing time Reliability to be in a failure-free condition at all times Efficiency to perform appropriately, relative to the amount of resources used Scalability to be easily and transparently upgradable Extensibility Security Maintainability to have consideration for future growth to keep away from security threats to be easily modifiable Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 25 Complessità computazionale • algoritmo : sequenza finita di operazioni, capace di risolvere un determinato problema in un tempo finito • programma : rappresentazione di un algoritmo mediante un linguaggio di programmazione • dimensione di un problema : intero positivo n proporzionale allo spazio occupato dai dati di ingresso relativi al problema • complessità temporale ( o spaziale ) di un algoritmo : indicazione del tempo ( o dello spazio) richiesto dall'algoritmo in funzione della dimensione n del problema Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 26 Complessità worst/average case • complessità nel caso peggiore ( worst-case ) : W(n) = max { t(I) I Dn } • Dn è l'insieme degli ingressi I di dimensione n • t(I) è il tempo di esecuzione relativo all'ingresso I • complessità media ( average-case ) : A(n) = I • p(I) t(I) Dn p(I) è la probabilità di I Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 27 Complessità Asintotica insieme delle funzioni che crescono con rapidità non superiore a quella di f(n) O( f(n) ) Q( f(n) ) insieme delle funzioni che crescono con rapidità uguale a quella di f(n) W( f(n) ) insieme delle funzioni che crescono con rapidità non inferiore a quella di f(n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 28 Notazione O O( f(n) ) è l'insieme di tutte le funzioni g(n) tali che esistano due costanti positive c e m per cui : g(n) c f(n) , "n ( n m ) g(n) O( f(n) ) se lim n g(n) f(n) =c O(c)O(log n) O( (log n)k ) O(n) O( n(log n)k ) O(nk) O( nk(log n)h ) O(nk+1) O(dn) La notazione O delimita superiormente la crescita asintotica della complessità e fornisce quindi una indicazione della bontà di un algoritmo Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 29 Notazione W W( f(n) ) è l'insieme di tutte le funzioni g(n) tali che esistano due costanti positive c e m per cui : g(n) c f(n) , g(n) W(f(n)) se f(n) O( g(n) ) "n ( n m ) lim n g(n) f(n) = c>0 se e solo se g(n) W( f(n) ) Un algoritmo di complessità O( f(n) ) si dice ottimo se qualunque algoritmo che risolva lo stesso problema ha complessità W ( f(n) ) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 30 Programming in the Small/Large • Programming in the small • software projects are developed by single programmers • main problems to be solved: • choice of appropriate data structures • development of efficient algorithms • Programming in the large • software projects are developed by large groups of programmers • different groups make • development (analysis, design, coding, integration, testing) • maintenance (extensions, upgrading) over large time intervals • main problems to be solved: • good choice of software components • communication of information among components • component integration Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 31 Sviluppo di algoritmi per raffinamenti successivi start definizione delle specifiche del problema la soluzione del problema è esprimibile direttamente nel linguaggio di programmazione prescelto ? si no scomposizione del problema in una sequenza , o selezione , o iterazione di sottoproblemi e definizione delle specifiche di ciascun sottoproblema codifica della soluzione si uno dei sottoproblemi generati coincide con uno dei problemi da cui è stato derivato ? no soluzione ricorsiva del problema scelta di un problema si ancora problemi da risolvere ? no stop Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 32 Massimo Comune Divisore (1) P /* a,b interi positivi */ CALCOLA MassimoComuneDivisore(a,b) /* MCD(a,b) */ MCD(a,b) = MCD(b,a) MCD(a,a) = a MCD(a,0) = a Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 33 Massimo Comune Divisore (2) MCD(a,a) = a P /* a,b interi positivi */ { int x,y; P1: INIZIALIZZA x,y ; /* MCD(x,y) = MCD(a,b) */ while (x!=y) P2: RIDUCI |x-y| SENZA VARIARE MCD(x,y) ; } /* x = MCD(a,b) */ P1 /* a,b interi positivi */ { x=a; y=b; } /* MCD(x,y) = MCD(a,b) */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 34 Massimo Comune Divisore (3) Se k è divisore comune di x e y x = k qx ; y = k qy |x-y| = k |qx - qy| k è divisore comune di |x-y| P2 /* MCD(x,y) = MCD(a,b); x!=y */ { if (x>y) x -= y; else y -= x; } /* MCD(x,y) = MCD(a,b) */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 35 Massimo Comune Divisore (4) P /* a,b interi positivi */ { int x,y; /* P1: INIZIALIZZA x,y */ x=a; y=b; /* MCD(x,y) = MCD(a,b) */ while (x!=y) /* P2: RIDUCI |x-y| SENZA VARIARE MCD(x,y) */ if (x>y) x -= y; else y -= x; } /* x = MCD(a,b) */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 36 Massimo Comune Divisore (5) public class Mcd1 { public static void main( String[] args ) { System.out.println("MCD(42,56)= "+ mcd(42,56)); } static int mcd(int a, int b) { while (a!=b) if (a>b) a -= b; else b -= a; return a; } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 37 Massimo Comune Divisore (6) MCD(a,0) = a P /* a,b interi positivi */ { int x,y; P1: INIZIALIZZA x,y ; /* MCD(x,y) = MCD(a,b) */ while (y!=0) P3: RIDUCI y SENZA VARIARE MCD(x,y) ; } /* x = MCD(a,b) */ P1 /* a,b interi positivi */ { x=a; y=b; } /* MCD(x,y) = MCD(a,b) */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 38 Massimo Comune Divisore (7) Se k è divisore comune di x e y x = k qx ; y = k qy x % y = x – (x / y) y = k(qx – (x / y) qy) k è divisore comune di x % y P3 /* MCD(x,y) = MCD(a,b); y!=0 */ { r = x % y; x = y; y = r; } /* MCD(x,y) = MCD(a,b) */ MCD(x,y) = MCD(y,x%y) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 39 Massimo Comune Divisore (8) P /* a,b interi positivi */ { int x,y,r; /* P1: INIZIALIZZA x,y */ x=a; y=b; /* MCD(x,y) = MCD(a,b) */ while (y!=0) /* P2: RIDUCI y SENZA VARIARE MCD(x,y) */ { r = x % y; x = y; y = r; } } /* x = MCD(a,b) */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 40 Massimo Comune Divisore (Euclide) public class Mcd2 { public static void main( String[] args ) { System.out.println("MCD(42,56)= "+ mcd(42,56)); } static int mcd(int a, int b) { int r; while (b!=0) { r = a % b; a = b; b = r; } return a; } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 41 Ricorsione n! = n*(n-1)! 1! = 1 Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 42 Algoritmi ricorsivi (MCD) MCD(a,b) = MCD(b,a%b) MCD(a,0) = a /* a,b interi positivi */ int mcd(int a, int b) { if (b==0) return a; else return mcd(b,a%b); } mcd(36,42) 6 mcd(42,36) 6 mcd(36,6) 6 mcd(6,0) 6 Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 43 Algoritmi ricorsivi (Fattoriale) n! = n*(n-1)! 1! = 1 /* n intero positivo */ int fact(int n) { if (n==1) return 1; else return n * fact(n-1); } fact(4) 24 fact(3) 6 fact(2) 2 fact(1) 1 complessità: O(n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 44 Algoritmi ricorsivi (Potenza) b¹ = b be = b * be-1 /* b,e interi positivi */ int pot(int b, int e) { if (e==1) return b; else return b * pot(b,e-1); } pot(3,4) 81 pot(3,3) 27 pot(3,2) 9 pot(3,1) 3 complessità: O(e) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 45 Algoritmi ricorsivi (Potenza) b¹ = b e pari be = (b * b)e/2 e dispari be = b * be-1 = b * (b * b)e/2 /* b,e interi positivi */ int pot(int b, int e) { if (e==1) return b; else if ((e & 1)==1) return b*pot(b*b,e/2); //e dispari else return pot(b*b,e/2); //e pari } pot(3,5) 243 pot(9,2) 81 pot(81,1) 81 complessità: O(log2 e) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 46 Algoritmi ricorsivi (Torri di Hanoi) 1 n sorgente intermedia destinazione P /* n dischi ordinati in s */ Sposta n dischi da s a d utilizzando i, muovendo un disco per volta e mantenendo l’ordinamento /* n dischi ordinati in d */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 47 Algoritmi ricorsivi (Torri di Hanoi) 1 n n-1 sorgente intermedia destinazione 1 n-1 n Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 48 Algoritmi ricorsivi (Torri di Hanoi) P /* n dischi ordinati in s */ { P: Sposta n-1 dischi da s a i utilizzando d, muovendo un disco per volta e mantenendo l’ordinamento; /* n-1 dischi ordinati in i */ P1: Sposta il disco n da s a d; P: Sposta n-1 dischi da i a d utilizzando s, muovendo un disco per volta e mantenendo l’ordinamento; } /* n dischi ordinati in d */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 49 Algoritmi ricorsivi (Torri di Hanoi) P /* n dischi ordinati in s */ void hanoi(int n, char s, char i, char d) { if (n==1) System.out.println("muovi 1 da " + s + " a " + d); else { hanoi(n-1,s,d,i); /* n-1 dischi ordinati in i */ System.out.println("muovi " + n + " da " + s + " a " + d); hanoi(n-1,i,s,d); } } /* n dischi ordinati in d */ Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 50 Algoritmi ricorsivi (Torri di Hanoi) public class Hanoi { public static void main( String[] args ) { hanoi(5,'S','I','D'); } static void hanoi(int n, char s, char i, char d) { if (n==1) System.out.println("muovi 1 da " + s + " a " + d); else { hanoi(n-1,s,d,i); System.out.println("muovi " + n + " da " + s + " a " + d); hanoi(n-1,i,s,d); } } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 51 Algoritmi ricorsivi (Torri di Hanoi) n n-1 n-2 20 n-1 n-2 n-2 21 n-2 22 1 1 1 1 1 1 1 1 … 2n-1 20 + 21 + 22 +…+ 2n-1 = 2n - 1 complessità: O(2n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 52 Algoritmi ricorsivi (Fibonacci) • L'intento di Fibonacci (Pisa, 1170-1240) era quello di trovare una legge matematica che potesse descrivere la crescita di una popolazione di conigli • Assumendo per ipotesi che: • • • • si disponga di una coppia di conigli appena nati questa coppia diventi fertile al compimento del primo mese e dia alla luce una nuova coppia al compimento del secondo mese le coppie fertili, dal secondo mese di vita in poi, diano alla luce una coppia di figli al mese le nuove coppie nate si comportino in modo analogo • si verifica quanto segue: • • • • • • • nel primo mese c’è 1 coppia di conigli (non fertile) nel secondo mese c’è 1 coppia (fertile) nel terzo mese ci saranno 1+1=2 coppie (1 fertile , 1 non fertile) nel quarto mese ci saranno 1+2=3 coppie (2 fertili , 1 non fertile) nel quinto mese ci saranno 2+3=5 coppie (3 fertili , 2 non fertili) … in ogni mese il numero totale di coppie è uguale alla somma dei numeri di coppie presenti nei due mesi precedenti: 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 , 144 , 233 , … Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 53 Algoritmi ricorsivi (Fibonacci) fib(n) = fib(n-1) + fib(n-2) fib(1) = 1 fib(0) = 0 Mario Merz: Il volo dei numeri Torino, Luci d’artista /* n intero positivo */ int fib(int n) { if (n<=1) return n; else return fib(n-1) + fib(n-2); } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 54 Algoritmi ricorsivi (Fibonacci) fib(4) fib(2) 1 fib(3) 2 fib(1) fib(2) 1 1 fib(1) 3 fib(1) fib(0) 1 0 fib(0) 1 0 complessità: O(2n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 55 Ricorsione Iterazione (Fibonacci) /* n intero positivo int fib(int n) { int f1=1; int f0=0; for (int i=1; i<n; { /* f1 = fib(i) , f1 += f0; /* f1 = fib(i+1) f0 = f1-f0; /* f1 = fib(i+1) } return f1; } */ i++) f0 = fib(i-1) */ , f0 = fib(i-1) */ , f0 = fib(i) */ complessità: O(n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 56 Algoritmi di ordinamento v insieme non ancora ordinato v insieme ordinato P v N-1 0 v 0 i N-1 v 0 int[] v; ... for(i=0; i<v.length; i++) { P1: SPOSTA UN ELEMENTO DI v DALLA PORZIONE NON ORDINATA A QUELLA ORDINATA } N-1 Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 57 Algoritmi di ordinamento (crescente) P1 P12: SELEZIONA IL PIU’PICCOLO ELEMENTO DELLA PORZIONE NON ORDINATA E SCAMBIALO CON QUELLO DI INDICE i v m 0 P1 N-1 i P13: INSERISCI L’ELEMENTO DI INDICE i NELLA PORZIONE ORDINATA, SPOSTANDO IN AVANTI QUELLI PIU’ GRANDI v 0 i N-1 Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 58 Ordinamento per selezione 3 m 1 P12 v 0 im i 2 N-1 m = v[i] ; im = i ; for(j=i+1; j<N; j++) if( v[j] < m ) { m = v[j]; im = j; } v[im] = v[i]; v[i] = m; Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 59 Ordinamento per selezione void selectSort(int[] v) { int i,j,m,im; int n = v.length; for (i=0; i<n-1; i++) { m = v[i]; im = i; for (j=i+1; j<n; j++) if( v[j] < m ) { m = v[j]; im = j; } v[im] = v[i]; v[i] = m; } } complessità: O(n2) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 60 Ordinamento per selezione public class Selectsort { public static void main(String[] args) { int[] a = {3,2,4,6,3,9,8,7,5}; selectSort(a); for(int i:a) System.out.print(i+" "); } static void selectSort(int[] v) { ... } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 61 Ordinamento per inserimento v i 0 N-1 x 1 4 v 0 P13 3 2 i N-1 x = v[i] ; for( j=i-1; j>=0 && x<v[j]; j-- ) v[j+1] = v[j]; v[j+1] = x; Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 62 Ordinamento per inserimento void insertSort(int[] v) { int i,j,x; int n = v.length; for (i=1; i<n; i++) { x = v[i]; for (j=i-1; j>=0 && x<v[j]; j--) v[j+1] = v[j]; v[j+1] = x; } } complessità: O(n2) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 63 Ordinamento per inserimento public class Insertsort { public static void main(String[] args) { int[] a = {3,2,4,6,3,9,8,7,5}; insertSort(a); for(int i:a) System.out.print(i+" "); } static void insertSort(int[] v) { ... } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 64 Quicksort v l P m h int[] v; ... { P1: PARTIZIONA GLI ELEMENTI DI v IN MODO TALE CHE OGNI ELEMENTO DELLA PARTIZIONE VERDE SIA MINORE DI (O UGUALE A) OGNI ELEMENTO DELLA PARTIZIONE ROSSA } P: ORDINA GLI ELEMENTI NELLA PARTIZIONE VERDE P: ORDINA GLI ELEMENTI NELLA PARTIZIONE ROSSA Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 65 Quicksort void quickSort(int[] v, int l, int h) { int m; if ( l < h ) { m = partition(v, l, h); /* P1 */ quickSort(v, l, m); quickSort(v, m+1, h); } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 66 Quicksort v[ i ] < x v[ j ] > x v i P1 j int partition ( int[] v, int i, int j ) { SCEGLI COME PERNO UN QUALUNQUE ELEMENTO x DI v while (true) { FINCHÈ v[i] < x INCREMENTA i /* v[i]>=x */ FINCHÈ v[j] > x DECREMENTA j /* v[j]<=x */ if ( i < j ) SCAMBIA TRA LORO v[i] E v[j] } } else return j Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 67 Quicksort P1 int partition(int[] v, int i, int j) { int x,t; x = v[(i+j)/2]; while (true) { while ( v[i] < x ) i++ ; while ( v[j] > x ) j-- ; if ( i < j ) { t = v[i]; v[i] = v[j]; v[j] = t; i++; j--; } else return j; } } complessità(partition): O(n) compl_media(quickSort): O(n log2 n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 68 Quicksort public class Quicksort { public static void main(String[] args) { int[] a = {3,2,4,6,3,9,8,7,5}; quickSort(a, 0, a.length-1); for(int i:a) System.out.print(i+" "); } static void quickSort(int[] v, int l, int h) { ... } static int partition(int[] v, int i, int j) { ... } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 69 Mergesort v l P l+h 2 h int[] v; ... { P: ORDINA LA PRIMA METÀ DI v P: ORDINA LA SECONDA METÀ DI v P1: FONDI LE DUE METÀ IN UN UNICO INSIEME ORDINATO } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 70 Mergesort void mergeSort(int[] v, int l, int h) { int m; if ( l < h ) { m = (l+h)/2; mergeSort(v, l, m); mergeSort(v, m+1, h); merge(v, l, h); /* P1 */ } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 71 Mergesort P1 void merge ( int[] v, int l, int h ) { COPIA LA PRIMA METÀ DI v IN aux NELLO STESSO ORDINE COPIA LA SECONDA METÀ DI v IN aux IN ORDINE INVERSO i = l; j = h; for (k = l; k <= h; k++) v[k] = (aux[j] < aux[i])? aux[j--]: aux[i++]; } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 72 Mergesort P1 void merge(int[] v, int l, int h) { int i,j,k,m; m = (l+h)/2; for (i = l; i <= m; i++) aux[i] = v[i]; for (j = m+1; j <= h; j++) aux[j] = v[h-j+m+1]; i = l; j = h; for (k = l; k <= h; k++) v[k] = (aux[j] < aux[i])? aux[j--]: aux[i++]; } complessità(merge): O(n) complessità(mergeSort): O(n log2 n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 73 Mergesort public class Mergesort { static int[] aux; public static void main(String[] args) { int[] a = {3,2,4,6,3,9,8,7,5}; aux = new int[a.length]; mergeSort(a, 0, a.length-1); for(int i:a) System.out.print(i+" "); } static void mergeSort(int[] v, int l, int h) { ... } static void merge(int[] v, int l, int h) { ... } } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 74 Algoritmi di ricerca insieme v x P int[] v; int x; ... { if ( x È UN ELEMENTO DI v ) return LA POSIZIONE DI x IN v ; else return -1 ; } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 75 Ricerca in insiemi non ordinati int search(int[] v, int x) { int i; int n = v.length; for (i=0; i<n; i++) if (x == v[i] ) return i; return -1; } complessità: O(n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 76 Ricerca in insiemi ordinati (crescenti) int search(int[] v, int x) { int i; int n = v.length; for (i=0; i<n && x >= v[i]; i++) if (x == v[i] ) return i; return -1; } complessità: O(n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 77 Ricerca dicotomica (binaria) in insiemi ordinati (crescenti) v l P l+h 2 h int[] v; int x; int m; ... { m = (l+h)/2; if ( x == v[m] ) return m ; else if ( x < v[m] ) P: RICERCA x NELLA PRIMA METÀ DI v; else P: RICERCA x NELLA SECONDA METÀ DI v; } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 78 Ricerca binaria (ricorsiva) int rbsearch(int[] v, int l, int h, int x) { int m; if ( l > h ) return -1; else { m = (l+h)/2; if ( x == v[m] ) return m; if ( x < v[m] ) return rbsearch(v, l, m-1, x); else return rbsearch(v, m+1, h, x); } } complessità: O(log2 n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 79 Ricerca binaria (iterativa) int ibsearch(int[] v, int l, int h, int x) { int m; while ( l <= h ) { m = (l+h)/2; if ( x == v[m] ) return m; if ( x < v[m] ) h=m-1; else l=m+1; } return -1 } complessità: O(log2 n) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 80 Ricerca indicizzata da chiave • Se gli elementi con chiave di ricerca x vengono memorizzati nella posizione x , il tempo di accesso è costante 0 325 x = v[x] … 325 … 673 673 … 729 729 xmax … • Tuttavia, se l’intervallo dei valori di x è molto più grande del numero di elementi da memorizzare, lo spreco di memoria diventa inaccettabile • Es: se 0 < x < 1000 e il numero di elementi è 100 , lo spreco è del 90% Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 81 Tabelle Hash • Una funzione hash trasforma una chiave x in un indice h(x) minore della dimensione N della tabella • Es: h(x) = x % N x = v[ h(x) ] N = 100 0 … 25 325 … 29 729 … 73 673 99 … • Se h(x1) = h(x2) , si verifica una collisione • Es: 729%100 = 29 = 29%100 = 129%100 = 229%100 = … Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 82 Risoluzione delle collisioni (con scansione lineare) • Quando si verifica una collisione ( la posizione h(x) è già occupata) , l’elemento con chiave x viene inserito nella prima posizione libera successiva • Es: N = 100 … 25 325 x = v[ (x%N + i)%N ] 26 -1 27 127 posizione k libera: v[k] = -1 28 29 528 30 -1 31 831 32 232 insert(427) 729 … Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 83 Tabella Hash a scansione lineare int[] v = new int[N]; for(int i=0; i< v.length; i++) v[i]= -1; void insert(int[] v, int x) { int i = x % v.length; while ( v[i] != -1 ) i = (i+1) % v.length; v[i] = x; } int search(int[] v, int x) { int i = x % v.length; while ( v[i] != -1 ) if (v[i] == x) return i; else i = (i+1) % v.length; return -1; } Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 84 Costo della scansione lineare • Nel caso peggiore la scansione lineare ha complessità O(n) ( n = numero di elementi presenti nella tabella ) • Il costo (numero di sondaggi) medio di una ricerca è: • 1 1 + 2 2(1-a) (ricerca con successo) • 1 1 + 2 2(1-a)2 (ricerca senza successo) • dove a = n / N è il fattore di carico • La complessità media di una ricerca è pertanto: • O( n / (N-n) ) • O( n2 / (N-n)2 ) (con successo) (senza successo) Silvano Rivoira - Dipartimento di Automatica e Informatica - Politecnico di Torino 85