260 likes | 402 Views
Begreber og Redskaber 7. BRP. Plan for idag. Rekursive underprogrammer Rekursive datastrukturer Rekursion vs iteration Rekursivt: Flette sortering. Fra første forelæsning. Grammatikken for regneudtryk i MiniJava Expression : VarName | Number
E N D
Plan for idag • Rekursive underprogrammer • Rekursive datastrukturer • Rekursion vs iteration • Rekursivt: Flette sortering
Fra første forelæsning Grammatikken for regneudtryk i MiniJava Expression : VarName | Number | ””” { Tegn } ””” | Expression ”+” Expression | Expression ”-” Expression | ”(” Expression ”)”
Rekursion • Et udtryk består af deludtryk • I et filsystem kan kataloger indeholde filer og kataloger • Andre ting kan opfattes rekursivt: En streng er enten tom eller et tegn foran en streng
Trekanter * ** *** * ** *** **** ***** public class Brp6{ public static void trekant(int i){ if(i>0){ trekant(i-1); while(i>0){ System.out.print("*");i--;} System.out.println(); } } public static void main(String args[]){ trekant(3); System.out.println(); trekant(5); System.out.println(); } }
Potensopløftning static int power(int x, int n){ int r = 1; while(n>0){ r = r*x; n=n-1; } return r; } static int rpower(int x, int n){ if(n==0) return 1; else return x*rpower(x,n-1); }
Iteration vs. rekursion • Iteration - gentag et antal gange • Rekursion: • for 0 returner 1 • for 1 returner x • for 2 returner x*x • for 3 returner x*x*x • for 4 returner x * det-der-skulle-returneres-for-3 • for 5 returner x * det-der-skulle-returneres-for-4
Fordele - ulemper • Rekursive løsninger er ofte korte og elegante. • Har man forstået det er det en enkel måde at udtrykke sig på • Har man ikke forstået det, så er det besværligt • Visse ting er vanskellige at gøre iterativt
Fjern blanktegn fra streng static String fjernblanke(String s){ String rs=""; for(int i=0;i<s.length();i++){ String s1=s.substring(i,1); if(!s1.equals(" "))rs=rs+s1; } return rs; }
Fjern blanktegn static String fjernblanke(String s){ if(s.equals("")) return ""; else if(s.charAt(0)==' ') return fjernblanke(s.substring(1)); else return s.substring(0,1)+ fjernblanke(s.substring(1)); }
Rekursiv tilgang Se på de nemme tilfælde. Se på om de besværligere tilfælde ikke kan løses ud fra løsning af nemmere tilfælde.
Besværligt iterativt • Gennemløb et filsystem og led efter filer med særlige egenskaber (feks. .bak) • Hvis iterativt skal man samle en liste med kataloger der skal undersøges • rekursivt: kig efter filerne og for alle underkataloger kald søgningen rekursivt
Rekursive datastrukturer class Liste{ int i Liste naeste; Liste(int ii,Liste nn){i=ii;naeste=n;} } Liste list=new Liste(1,new Liste(2,null));
Fletning Flettesortering De to lister [5, 9, 10] og [1, 8, 11] er begge sorterede En samlet og sorteret liste [1, 5, 8, 9, 10, 11] ønskes. En sådan kan fås vha. sammenfletning
Fletning De to lister flettes sammen på følgende vis [] <- [5, 9, 10] [1, 8, 11] [1] <- [5, 9, 10] [8, 11] [1, 5] <- [9, 10] [8, 11] [1, 5, 8] <- [9, 10] [11] [1, 5, 8, 9] <- [10] [11] [1, 5, 8, 9, 10] <- [] [11] [1, 5, 8, 9, 10, 11] <- [] []
Flettesortering Flettesortering af en liste heltal Der er to tilfælde 1. Listen har eet element -- Der skal da ikke gøres noget 2. Listen har mere end eet element -- Listen deles op i to mindre lister -- Hver af de to mindre lister flettesorteres -- De to resulterende lister flettes sammen Bemærk: Basis og rekursivt tilfælde
Fletning Sorteret Sorteret
Fletning static void merge(int[] tb,int[] tm, int from,int mid,int to){ int n = to-from+1; int i1=from, i2=mid+1, j=0; while(i1<=mid && i2 <= to){ if(tb[i1]<tb[i2]){ tm[j]=tb[i1];i1++;j++; }else{ tm[j]=tb[i2];i2++;j++; } } while(i1<=mid){tm[j]=tb[i1]; i1++;j++;} while(i2<=to ){tm[j]=tb[i2]; i2++;j++;} for(j=0;j<n;j++)tb[from+j]=tm[j]; }
Flettesortering static void mergesort(int[] tb,int[] tm, int from,int to){ if(from==to) return; int mid=(to+from)/2; mergesort(tb,tm,from,mid); mergesort(tb,tm,mid+1,to); merge(tb,tm,from,mid,to); } static void sort(int[] tb){ int tm[]=new int[tb.length]; mergesort(tb,tm,0,tb.length-1); }
Figure 2 Merge Sort Timing (Rectangles) versus Selection Sort (Circles)
Logaritmer • Det omvendte af potenser 105=100000 100=1 log10(100000)=5 log10(1)=0 28=256 20=1 log2(256)=8 log2(1)=0 • Regne med potenser og logaritmer an+m=an * am log(n * m)=log(n)+log(m)
Køretid – groft overslag Ide: halver tabel – sorter hver del og flet. Fletning er i lineær tid (dvs n), men hvor mange gange kan man halvere en tabel? Lad n være tabellens længde. Køretid i størrelsesordenen n * log2(n)
Køretid For merge(.. from,mid,to) gennemløbes elementerne fra ”from” til ”to” 2 gange Køretid af mergesort: T(n) = T(n/2)+T(n/2)+2*n = 2*(T(n/2)+n) udfold: T(n)=2*(2*(T(n/4)+n/2)+n) T(n)=2*(2*(2*(T(n/8)+n/4)+n/2)+n)
Køretid T(n)=2*(2*(T(n/4)+n/2)+n) =4*T(n/4)+4*n T(n)=2*(4*T(n/8)+4*n/2)+n)=8*T(n/8)+6*n T(n)=2*(8*T(n/16)+6*n/2)+n)=16*T(n/16)+8*n T(n)=2k+2*k*n , hvor k er antal gange man kan halvere – altså log2(n) O(log2(n)*n)
Eksempel Antal sammenligninger (<): Tabel med 1000 udvalgssortering: 499500 Flettesortering: 8706 Tabel med 10000 udvalgssortering: 49995000 Flettesortering: 120472
Konklusion Det at funktionen n·log(n) vokser mindre end funktionen n2 forklarer hvorfor det er mere effektivt at flettesortere end at udvalgssortere.