• Non ci sono risultati.

Struttura dei dati

N/A
N/A
Protected

Academic year: 2021

Condividi "Struttura dei dati"

Copied!
9
0
0

Testo completo

(1)

Ricerca e ordinamento

Paolo Bison

Fondamenti di Informatica Ingegneria Meccanica

Università di Padova A.A. 2008/09

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.1

Struttura dei dati

 si considera una sequenza di N dati d 0 d 1 d 2 ... d N−1 memorizzati in un array

 si deve avere una relazione d’uguaglianza = ed una d’ordine ⊑ applicabile

 ai singoli dati (d i = d j d i ⊑ d j )

 ad elementi k i ( k i = k j k i ⊑ k j ) calcolato ciascuno dal corrispondente dato d i

k i = K( d i ) con 0 ≤ i < N

• key (chiave)

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.2

Rappresentazione dei dati

 user-defined type (struttura) type,public :: datum

integer :: key

character(len=256) :: info ! payload end type

 chiave codificata in maniera esplicita

 modulo dbarray.f90

Ricerca

 trovare in una sequenza di dati

d 0 d 1 d 2 ... d N−1

un particolare elemento ¯d, se esiste, tale per cui si abbia

¯d=d i con 0 ≤ i < N

 ricerca per chiave

data un chiave ¯k trovare il dato ¯d tale per cui

(2)

Ricerca lineare

 cercare il valore 12 nel seguente array

18 0 17 12 8 20

18 0 17 12 8 20

18 0 17 12 8 20

18 0 17 12 8 20

18 0 17 12 8 20

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.5

Ricerca lineare

 algoritmo

 si confronta un dato alla volta in maniera sequenziale finché non si trova l’elemento cercato o termina la sequenza

 codice Fortran

function ricerca(a,key,ris) result(trovato) type(datum),dimension(:),intent(in) :: a integer,intent(in) :: key

type(datum),intent(out) :: ris logical :: trovato

integer :: i,n n=ubound(a,1) do i=1,n

if (a(i)%key==key) then; exit; end if end do

trovato=i<=n

if (trovato) then; ris=a(i); end if end function ricerca

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.6

Ricerca lineare: prestazioni

 valutazione numero di accessi all’array

 se il dato cercato non è presente, sono necessari n accessi

 se il dato è presente, il numero di accessi dipende dalla posizione del dato nell’array

• in media n/2

 complessità

O(n)

Ricerca binaria

 cercare il valore 12 nel seguente array ordinato

5 9 11 12 17 21

5 9 11 12 17 21

5 9 11 | 12 17 21

5 9 11 | 12 17 21

5 9 11 | 12 | 17 21

5 9 11 | 12 | 17 21

(3)

Ricerca binaria

 algoritmo

 si confronta l’elemento di mezzo con il dato cercato

 se non è tale dato

• se è maggiore si cerca in modo binario nel sotto-array a sx

• altrimenti nel sotto-array di dx

 si termina quando si trova l’elemento oppure si ha un sotto-array vuoto

 dicotomica o per bisezione

 applicabile solo se i dati sono ordinati

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.9

Ricerca binaria: codice Fortran

function ricerca(a,key,ris) result(trovato) type(datum),dimension(:),intent(in) :: a integer,intent(in) :: key

type(datum),intent(out) :: ris logical :: trovato

integer :: i,j,k,n n=ubound(a,1); i=1; j=n do

k = (i+j)/2

if ((a(k)%key==key).or. (i>j)) then exit

end if

if (a(k)%key>key) then j=k-1

else i=k+1 end if end do trovato=i<=j

if (trovato) then; ris=a(k); end if end function ricerca

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.10

Ricerca binaria: prestazioni

 numero di confronti necessari per trovare un dato

 dato un array di dimensione n si deve

 effettuare un confronto con l’elemento centrale

 effettuare una ricerca in un array di dimensione n/2 per cui

T (n) = T (n/2) + 1 la cui soluzione è

T (n) = 1 + log 2 n

 complessità

O(log n)

lineare vs. binaria

 tempi di esecuzione in sec key lineare binaria

1 0.43 0.48

10000000 0.74 0.47 20000000 1.06 0.51

0 1.07 0.52

(4)

Ordinamento

 data una sequenza di dati

d 0 d 1 d 2 · · · d N−2 d N−1 generare un altra sequenza

d k

0

d k

1

d k

2

· · · d N −2 d k

N−1

tale per cui

K ( d k

0

) ≤ K( d k

1

) ≤ K( d k

2

) ≤ · · · ≤ K( d k

N−2

) ≤ k( d k

N−1

)

 ordinamento in loco

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.13

Ordinamento per selezione

3 -7 5 7 -1

3 -7 5 7 -1

-7

|

3 5 7 -1

-7

|

3 5 7 -1

-7 -1

|

5 7 3

-7 -1

|

5 7 3

-7 -1 3

|

7 5

-7 -1 3

|

7 5

-7 -1 3 5

|

7

-7 -1 3 5

|

7

-7 -1 3 5 7

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.14

Ordinamento per selezione: algoritmo

 dato un array di N elementi si cerca il dato più piccolo

 si scambia questo elemento con il primo

 si considera il sotto-array di dimensione N − 1 composto da tutti i dati eccetto il primo

 si riapplica il medesimo algoritmo

Ordinamento per selezione: codice Fortran

subroutine sort(a)

type(datum),dimension(:),intent(inout) :: a integer :: i,j,k

integer :: n type(datum) :: x n=ubound(a,1) do i=1,n-1

k = i; x = a(i) do j=i+1,n

if (a(j)%key<x%key) then k = j; x = a(j) end if

end do

a(k) = a(i); a(i) = x end do

end subroutine sort

(5)

Ordinamento per selezione: prestazioni

 calcolo del numero di accessi

 dati N elementi

N accessi per trovare il minimo

• 3 accessi per lo scambio in totale, ( N +3)

 per ordinare i rimanenti N -1 dati (( N -1)+3)

 e via fino a N =2

 totale accessi

( N +3)+(( N -1)+3))+ · · · +(3+3)+(2+3)

= 1 2 N 2 + 9 2 N − 4

 complessità O(n 2 )

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.17

Ordinamento per inserimento

3 -7 5 7 -1

3

|

-7 5 7 -1

3

|

-7 5 7 -1

-7 3

|

5 7 -1

-7 3

|

5 7 -1

-7 3 5

|

7 -1

-7 3 5

|

7 -1

-7 3 5 7

|

-1

-7 3 5 7

|

-1

-7 3 5 -1 7

|

-7 3 -1 5 7

|

-7 -1 3 5 7

| Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.18

Ordinamento per inserimento: algoritmo

 si eseguono N − 1 passi

 ad ogni passo si considera i dati divisi in due parti

 una ordinata 0 ≤ k < i

 una non ordinata i ≤ m ≤ N − 1

 si prende il primo dato presente nella parte non ordinata e lo si inserisce in quella ordinata

 per inserirlo si sposta a dx dati che siano maggiori di quello da inserire

 ad ogni passo la parte ordinata aumenta di una unità mentre quella non ordinata diminuisce di 1

Ordinamento per inserimento: codice

subroutine sort(a)

type(datum),dimension(:),intent(inout) :: a integer :: i,j

integer :: n type(datum) :: x n=ubound(a,1) do i=2,n

x = a(i); j=i-1 do

if (j==0) then; exit; end if if (a(j)%key<=x%key) then

exit end if a(j+1)=a(j) j=j-1 end do a(j+1) = x

(6)

Ordinamento per inserimento: prestazioni - I

 caso migliore

 dati già ordinati

 nessuna iterazione del ciclo interno, solo un accesso per il confronto

 il ciclo esterno viene eseguito N − 1 volte

 totale accessi: 3(N − 1)

 complessità O(n)

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.21

Ordinamento per inserimento: prestazioni - II

 caso peggiore

 dati ordinati a rovescio

 il ciclo interno deve spostare tutti i dati già ordinati

 totale accessi: 2(N − 1) + 3N(N−1) 2

 complessità O(n 2 )

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.22

Ordinamento per inserimento: prestazioni - III

 caso medio

 dati in ordine casuale

 il ciclo interno deve spostare in media metà dei dati già ordinati

 totale accessi: 2(N − 1) + 3N(N−1) 4

 complessità O(n 2 )

Bubble sort

3

-7

5

7

-1 3

-7

5

7

-1 3

-7

5

7

-1 3

-7

5

-1

7 3

-7

5

-1

7 3

-7

-1

5

7 3

-7

-1

5

7 3

-7

-1

5

7 -7

3

-1

5

7 -7

3

-1

5

7 -7

3

-1

5

7 -7

3

-1

5

7 -7

-1

3

5

7 -7

-1

3

5

7 -7

-1

3

5

7

-7

-1

3

5

7

-7

-1

3

5

7

(7)

Bubble sort: algoritmo

 a turno si compara coppie adiacenti di dati scambiandoli se necessario

 si ripete questo passo per tutti i possibili confronti oppure finché non è avvenuto nessun scambio

 dati più piccoli risalgono verso l’inizio della sequenza

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.25

Bubble sort: codice

subroutine sort(a)

type(datum),dimension(:),intent(inout) :: a integer :: i,j

integer :: n type(datum) :: x n=ubound(a,1) do i=2,n

do j=n,i,-1

if (a(j-1)%key>a(j)%key) then x=a(j)

a(j)=a(j-1) a(j-1)=x end if end do end do

end subroutine sort

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.26

Bubble sort: prestazioni

 il ciclo esterno viene eseguito N − 1 volte

 il numero di iterazioni del ciclo interno diminuisce di uno ad ogni iterazione di quello esterno

 totale accessi (caso migliore):

2 (N−2)(N−3) 2

 complessità O(n 2 )

Merge sort

3 -7 5 7 -1

3 -7 | 5 7 -1

3 -7 | 5 | 7 -1

| X 7 -1 X

| X 5 -1 X X 7 -7 X X 3 -1 X X 5 X 7

-7 -1 3 5 7

-7 -1 3 5 7

(8)

Merge sort: algoritmo

 se la sequenza è formata da un solo dato è ordinata

 altrimenti

 si divide la sequenza in due sotto-sequenze (circa) uguali

 si ordina la prima sotto-sequenza con il merge sort

 si ordina la seconda sotto-sequenza con il merge sort

 si fondono (merge) le due sequenze ordinate costruendo una nuova sequenza ordinata

• prendendo un dato alla volta dalla sotto-sequenza il cui primo dato è il minore

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.29

Merge sort: codice - I

subroutine sort(a)

type(datum),dimension(:),intent(inout) :: a call mergeSort(a,size(a,1))

end subroutine sort

recursive subroutine mergeSort(a,N)

type(datum),dimension(:),intent(inout) :: a integer,intent(in) :: N

integer :: mid

type(datum),dimension(N/2) :: left type(datum),dimension(N-N/2) :: right if (N>1) then

mid=N/2 left=a(1:mid) right=a(mid+1:N)

call mergeSort(left,size(left,1)) call mergeSort(right,size(right,1)) call mergeOrder(a,left,right) end if

end subroutine mergeSort

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.30

Merge sort: codice - II

subroutine mergeOrder(a,b,c) ! combina b e c in a in maniera ordinata type(datum),dimension(:),intent(out) :: a

type(datum),dimension(:),intent(in) :: b,c; integer :: ia,ib,ic,l ia=1; ib=1; ic=1;

do

if (ib>size(b,1) .or. ic>size(c,1)) then exit

end if

if (b(ib)%key<c(ic)%key) then a(ia)=b(ib); ib=ib+1;

else

a(ia)=c(ic); ic=ic+1;

end if ia=ia+1 end do

do l=ib,size(b,1) ! eseguito se size(b) >size(c) a(ia)=b(ib); ib=ib+1;ia=ia+1

end do

do l=ic,size(c,1)! eseguito se size(c) >size(b) a(ia)=c(ic); ic=ic+1;ia=ia+1

Merge sort: prestazioni

 numero di accessi

 le copie di array richiedono 2N accessi

 ogni invocazione ricorsiva richiede T (N/2) accessi

 fusione necessita di 3N accessi ( N per leggere e 2N per scrivere)

 totale accessi :

T (N) = T (N/2) + 5N T (N) = N + 5N log 2 (N)

 complessità O(n log(n))

(9)

Confronto tra ordinamenti

migliore medio peggiore

selection n 2 n 2 n 2

insertion n n 2 n 2

bubble n 2 n 2 n 2

merge n log n n log n n log n

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.33

Prestazioni

 tempi di esecuzione in sec per ordinare un array di 10000 elementi:

-1 2 -3 4 -5 ... -9995 9996 -9997 9998 -9999 10000

lineare inserimento bubble merge

9.92 17.31 25.70 0.10

Ricerca e ordinamento, Paolo Bison, FI08, 2008-09-29 – p.34

Riferimenti

Documenti correlati

codifica a 16 bit: maggior parte dei caratteri usano una sola word, altri due.

Introduzione alla logica matematica, Paolo Bison, FI08, 2008-09-29 – p.29. Do it yourself

Introduzione alla logica matematica, Paolo Bison, FI08, 2008-09-29 – p.1..

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 –

Basic Fortran (cont.), Paolo Bison, FI08, 2008-09-29 –

Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.17. user-defined type

Fondamenti di Informatica Ingegneria Meccanica. Università di

validità di una associazione definita in termini della struttura statica del programma. Introduzione al corso, Paolo Bison, FI08, 2008-12-09