Dagens tema Sortering. Fortsettelse om programmering vha tråder.
«orden» i dataene vi blir fort lei av å lete poleksempel internett «alt» er søking og sortering alternativer til sortering og søking binære trær søketrær michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 2
Forutsetter at vi kan rangere elementene. Gitt to elementer, programmet må kunne teste om det ene elementet er lik, mindre enn eller større enn det andre, jf. grensesnittet Comparable med metoden compareto... I eksemplene sorterer vi ofte enkle «objekter» som heltall, tegn eller strenger. Ikke vanskeligere å sortere komplekse objekter så lenge de er «sammenlignbare». Litt mer formaliteter: Med en sortert array mener vi en array (A) der A[0] A[1] A[2] A[3] A[n 2] A[n 1] michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 3
1. Sorterering ved bruk av binærtre som «mellomlager» Programmeringsidé: Sett objektene inn i et binært søketre. Etter at alle er satt inn, ta dem ut i sortert orden (hvordan?) og sett dem inn i arrayet i sortert orden. michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 4
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 5
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 6
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 7
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 8
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 9
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 10
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 11
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 12
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 13
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 14
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 15
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 16
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 17
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 18
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 19
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 20
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 21
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 22
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 23
michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 24
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 25
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 26
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 27
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 28
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 29
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 30
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 31
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 32
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 33
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 34
kryss michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 35
2. Boblesortering Idé: Gå igjennom arrayet og for hver gang man finner to elementer ved siden av hverandre som ligger feil i forhold til sorteringskriteriet, bytt dem. Gjenta gjennomgangen til ingen bytter blir gjort. Påstand: Hvis det ikke finnes to elementer ved siden av hverandre som ikke oppfyller sorteringsregelen, må hele arrayen være sortert. michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 36
3. Flettesortering Algoritmeidé: Del arrayen opp i delarrayer, slik at hver delarray er sortert (et array med ett element er sortert). Flett sammen to og to arrayer til større sorterte delarrayer til det er et array igjen. michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 37
4. Innstikksortering Generell idé: Plukk ett og ett element fra listen og sett det inn på rett plass (sortert) i en ny liste. 1. Finn første element fra venstre som er mindre enn det til venstre for seg ta dette ut. 2. Elementene til venstre for dette skyves mot høyre inntil det uttatte elementet «passer inn». 3. Gjenta 1 2 inntil det siste elementet (helt til høyre) er behandlet. Invariant: A[0 : k] er sortert for k som løper fra 0 til lengden av A 1. michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 38
I programeksemplet nedenfor sorteres et array av tegn, char[] a. void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 39
a c d g h n q e u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 40
e a c d g h n q e u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 41
e a c d g h n q q u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 42
e a c d g h n n q u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 43
e a c d g h h n q u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 44
e a c d g g h n q u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 45
e a c d e g h n q u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 46
a c d e g h n q? u s o r t e r t void innstikksortering ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { i f ( a [ k + 1] < a [ k ] ) { // a[ k + 1] står på f e i l plass char tmp = a [ k + 1 ] ; int i = k ; while ( i >= 0 && a [ i ] > tmp) { // a[ i ] > tmp, f l y t t t i l høyre a [ i + 1] = a [ i ] ; i ; // s e t t tmp på rett plass a [ i +1] = tmp; michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 47
En bedre variant? void innstikksorteringvar1 ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { \\ n = a. length 1 \\ A[ 0 : k 1] har de minste elementene og er sortert \\ finner minste element i A[ k : n] på plass j \\ bytt A[ k ] med A[ j ] \\ resultat : A[ 0 : k ] har de minste elementene og er sortert michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 48
Programmerer ut løkka som finner minste element i A[k : n]: void innstikksorteringvar1 ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { \\ n = a. length 1 \\ A[ 0 : k 1] har de minste elementene og er sortert int minsthittil = A[ k ] ; j = k ; for ( int i = k ; i < a. length 1; i ++) i f (A[ i ] < minsthittil ) { minsthittil = A[ i ] ; j = i ; \\ bytt A[ k ] med A[ j ] \\ resultat : A[ 0 : k ] har de minste elementene og er sortert michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 49
Programmerer ut byttet som medfører at den sorterte delen øker med ett element: void innstikksorteringvar1 ( char [ ] a ) { for ( int k = 0; k < a. length 1; k++) { \\ A[ 0 : k 1] har de minste elementene og er sortert int minsthittil = A[ k ] ; j = k ; for ( int i = k ; i < a. length 1; i ++) i f (A[ i ] < minsthittil ) { minsthittil = A[ i ] ; j = i ; int tmp = A[ k ] ; A[ k ] = A[ j ] ; A[ j ] = tmp; \\ A[ 0 : k ] har de minste elementene og er sortert \\ A[ 0 :n] har de minste elementene og er sortert michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 50
Tilstandspåstander Java datastrukturdiagrammer A[0 : k] er sortert i : 0 i < k : A[i] A[i + 1] Alle elementer i A[k : l] er mindre enn alle elmentene i A[m : n] k i l, m j n : A[i] < A[j] Lista inneholder aldri mer enn n objekter... michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 51
Invariante tilstandspåstander påstander som ikke forandrer seg Det er aldri et ulovlig tall i en rute i sudokubrettet A[0 : k] er sortert er en invariant påstand hvis sannhetsverdien ikke forandrer seg når k endrer verdi.... michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 52
Om effektivitet Ikke viktig i INF1010, men vi skal se opp for lange løkker inni hverandre flere rekursive kall i en metode n! når n er stor multiplisering av objekter (metodekall og tråder) uten øvre grense Men effektivitet er et hovedkriterium når vi skal velge lage et godt program/algoritme. michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 53
Programmeringsøvelser til plenumsøvelsen 1. Gjør skriv-metoden i binærtreeksemplet om slik at den istedet leverer en array med objektene i sortert rekkefølge. 2. Skriv en metode som tar to sorterte arrayer som parameter og returnerer en sortert array ved å flette dem sammen. 3. Skriv en metode som boblesorterer et heltallsarray. 4. Skriv en metode som sorterer etter følgende idé (innstikksortering. Invariant?): 4.1 Finn det minste elementet i arrayen ta dette ut. 4.2 Sett det uttatte elementet i fifo-orden inn i et nytt array. 4.3 Gjenta 4.1 4.2 inntil det siste elementet i det første arrayet er tatt ut. michael@ifi.uio.no INF1010 15. april 2010 (uke 15) 54