Föreläsning 1, vecka 7: Rekursion

Relevanta dokument
Föreläsning 11: Rekursion

Föreläsning 12: Exempel och problemlösning

Rekursion och induktion för algoritmkonstruktion

Föreläsning 8: Exempel och problemlösning

Föreläsning 6: Metoder och fält (arrays)

Föreläsning 2, vecka 8: Repetition

Rekursion och induktion för algoritmkonstruktion

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

Rekursion. Koffman & Wolfgang kapitel 5

Instuderingsfrågor, del D

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

Rekursion och induktion för algoritmkonstruktion

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

Föreläsning 3: Booleans, if, switch

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Föreläsning 13. Rekursion

Objektorienterad programmering E. Back to Basics. En annan version av printtable. Ett enkelt exempel. Föreläsning 10

Exempel: Förel Rekursion III Nr 14. Uno Holmer, Chalmers,

Algoritmanalys. Inledning. Informationsteknologi Malin Källén, Tom Smedsaas 1 september 2016

Rekursion. Att tänka rekursivt Att programmera rekursivt i Java Exempel. Programmeringsmetodik -Java 254

OOP Objekt-orienterad programmering

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

Föreläsning 2 Datastrukturer (DAT037)

Objektorienterad programmering. Fält som funktionsresultat. Mer om fält: att uppdatera ett parameterfält. Kontrast: Parametrar av primitiv typ

F11 - Rekursion. ID1004 Objektorienterad programmering Fredrik Kilander

Sökning och sortering

Uppgift: Algoritm för att beräkna kontrollsiffran i ett personnummer givet de 9 första siffrorna. Torrsimning av algoritm för personnummer

Tentamen. Lösningsförslag

Föreläsning 9 Innehåll. Söndra och härska. Fibonaccitalen. Söndra och härska. Divide and conquer teknik för att konstruera rekursiva algoritmer.

Föreläsning 5. Rekursion

Lösningsförslag till exempeltenta 1

Föreläsning 2 Datastrukturer (DAT037)

String [] argv. Dagens Agenda. Mer om arrayer. Mer om arrayer forts. String [] argv. argv är variabelnamnet. Arrayer och Strängar fortsättning

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

DAT043 Objektorienterad programmering för D, DIT011 Objektorienterad programvaruutveckling för GU

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

4 13 / %.; 8 </" '': " / //&' " " ' * TelefonKostnad +,-%&. #!" $% " &' . > / ' 5 /' * 13/ &' static Math 1+" &'/ % 12 "" static "' * 1 /") %& &

Objektorienterad programmering E. Algoritmer. Telefonboken, påminnelse (och litet tillägg), 1. Telefonboken, påminnelse (och litet tillägg), 2

Föreläsning 1, vecka 8: Att förbereda sig för tentan

Medan ni väntar. 2. Skriv metoden. 3. Skriv metoden. Naturligtvis rekursivt och utan användning av Javas standardmetoder.

Den som bara har en hammare tror att alla problem är spikar

Detta dokument är ett exempel, cirka hälften av en tentamen för TDA545 Objektorienterad programvaruutveckling

Algoritmer. Två gränssnitt

Föreläsning 3-4 Innehåll

Föreläsning 2, vecka 6: Tillstånd i objektorienterade program (och mera interface)

Lösningsförslag till omtentamen för TDA540 Objektorienterad Programmering

Föreläsning 9 Innehåll. Söndra och härska. Fibonaccitalen. Söndra och härska. Divide and conquer teknik för att konstruera rekursiva algoritmer.

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Föreläsning 6 Innehåll. Rekursion. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursiv problemlösning. Rekursion. Rekursivt tänkande:

Laboration 13, Arrayer och objekt

Föreläsning 8 Innehåll

Idag. Exempel, version 2. Exempel, version 3. Ett lite större exempel

Lösningsförslag till tentamen för TDA540 Objektorienterad Programmering

Modelsvar för Tentamen för Objektorienterad programvaruutveckling, TDA545

TENTAMEN OOP

Omtentamen för TDA540 Objektorienterad Programmering. Institutionen för Datavetenskap CTH HT-16, TDA540. Dag: , Tid:

Detta dokument är ett exempel, cirka andra hälften av en tentamen för TDA545 Objektorienterad programvaruutveckling

Del A (obligatorisk för alla)

Föreläsning 2. Länkad lista och iterator

Institutionen för TENTAMEN CTH VT-15 Datavetenskap TDA540. Tentamen för TDA540 Objektorienterad programmering

Lite mer om Javas stöd för fält. Programmering. Exempel: vad är det största talet? hh.se/db2004. Fält samt Input/Output

Lösningsförslag till exempeltenta 2

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Programmering för språkteknologer II, HT2011. Rum

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Tentamen OOP

Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

Del A (obligatorisk för alla)

D0010E. Hello world! Nedräkning. Sågtand. Övningsuppgifter i Eclipse. Skapa ett program som skriver ut "Hello world" på skärmen.

1 Uppgift 1. a) Skapar ett Company-objekt med hjälp av den överlagrade konstruktorn. Du kan själv välja värden på instansvariablerna.

Metodanrop - primitiva typer. Föreläsning 4. Metodanrop - referenstyper. Metodanrop - primitiva typer

Föreläsning 5&6 LOGISKA VARIABLER; IMPLEMENTERA KLASSER; MER ALGORITMER

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Föreläsning 2. Länkad lista och iterator

OOP Objekt-orienterad programmering

Programmering för språkteknologer II. OH-serie: Sökning och sortering. Algoritm

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 12

Tentamen i Grundläggande Programvaruutveckling, TDA548

Föreläsning 11 Datastrukturer (DAT037)

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

Lektion 1 - Programmeringsteknik F1, ht 2003

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Muddy. Funktioner / metoder. Punktnotation. Evalueringsordning

Exempel på listor (klassen ArrayList). Ett exempel med fält. Avbildning är en speciell typ av lista HashMap.

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Dagens text. Programmeringsteknik. Mer om Scanner-klassen. Dialogrutor (klassen JOptionPane) Bubbelsortering. Omslagsklasser.

F6 Objektorienterad design. ID1004 Objektorienterad programmering Fredrik Kilander

Programmeringsteknik och Matlab. Dagens program. Viktiga datum. Repetitionsexempel. Repetition av if/else, for, while och Scanner

JAVAUTVECKLING LEKTION 4

Algoritmer och datastrukturer H I HÅKAN S T R Ö M B E R G N I C K L A S B R A N D E F E L T

Kungl. Tekn. Högskolan Förel 1, bild 1 Föreläsning 1: Introduktion ffl Kursinnehåll ffl Javarepetition ffl Referenser ffl Nyckelordet static ffl Klass

Föreläsning REPETITION & EXTENTA

Dagens text. Programmeringsteknik. Mer om Scanner-klassen. Dialogrutor (klassen JOptionPane) Bubbelsortering. Omslagsklasser.

Tentamen i Objektorienterad programmering E

OOP Objekt-orienterad programmering

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Föreläsning 6: Introduktion av listor

Föreläsning 3. Stack

Tänk på följande: Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Lösningsförslag till tentamen för TDA540 Objektorienterad Programmering

Transkript:

TDA 548: Grundläggande Programvaruutveckling Föreläsning 1, vecka 7: Rekursion Magnus Myréen Chalmers, läsperiod 1, 2016-2017

Nytt: Extra labbtillfälle för Grupp B (för att grupp Bs labbtider har på senaste tiden kolliderat med GruDat) E studion 13-15 onsdag 12 oktober 2016 E studion 15-17 torsdag 13 oktober 2016

Feedback Hur fungerar labbarna? Hur fungerar övningarna? Fungerar övning före föreläsning?

Idag Rekursion fakulteten exponentiering binary search Fibonacci 91 funktionen quick sort men också: jämförelse med iteration att mäta tid i Java roliga problem live programmering Nästa gång: mera objektorientering, i detta fall: arv, subtyper, API

Att tänka rekursivt Hur långt är tåget? Rekursivt svar: om det inte finns tågvagnar: då är dess längd 0 i övriga fall: längden är 1 + längden av resten av tåget samma fråga som ursprungligen, men med mindre indata (input)

Fakulteten Iterativt n! = 1 if n<1 1 2 3... n if 1 apple n public static int facit(int n) { int v = 1; for (int i=1; i<=n; i++) { v = v * i; return v; Induktivt eller rekursivt n! = 1 if n<1 n (n 1)! if 1 apple n

Induktiva definitioner använder självreferens, t.ex. En kö är antingen tom eller en person följt av en kö. n! är 1, om n är 0 eller 1, eller n (n-1)! om n är större. n! = 1 if n<1 n (n 1)! if 1 apple n Induktiva definitioner består av 1. Ett basfall 2. Ett fall där definitionen (vanligen) minskar problemets storlek och refererar till sig själv.

Induktionsbevis och rekusion Induction poof: to prove that a statement P(n) holds for all integers n Base case: Prove P(0) ( or P(small number)) Assumption: assume that P(n-1) is true (or P(n), P(n/2)... is ) Induction step: prove that P(n-1) implies P(n) for all n 0 Recursive computations: Base case: Solve the problem on inputs of size 0 (or 1 or some small instance) Assumption: assume you can solve the problem on input size less than n (n-1, n/2, n/4...) Induction step: Show how you can solve it also on inputs of size n for all n!1. Med stöd av detta kan problemet lösas med

Fakulteten (forts) Iterativt n! = 1 if n<1 1 2 3... n if 1 apple n public static int facit(int n) { int v = 1; for (int i=1; i<=n; i++) { v = v * i; return v; Induktivt eller rekursivt n! = 1 if n<1 n (n 1)! if 1 apple n public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1);

Evaluering System.out.println(fac(4)); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1);

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1);

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1);

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); if (2 < 1) { else { return 2 * fac(1);

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); if (2 < 1) { else { return 2 * fac(1); if (1 < 1) { else { return 1 * fac(0);

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); if (2 < 1) { else { return 2 * fac(1); if (1 < 1) { else { return 1 * fac(0); 1

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); if (2 < 1) { else { return 2 * fac(1); rekursionen går ner if (1 < 1) { else { return 1 * fac(0); 1

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); if (2 < 1) { else { return 2 * fac(1); rekursionen kommer upp if (1 < 1) { else { return 1 * fac(0); 1

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); if (2 < 1) { else { return 2 * fac(1); rekursionen kommer upp if (1 < 1) { else { return 1 * 1;

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * fac(2); rekursionen kommer upp public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); if (2 < 1) { else { return 2 * 1;

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * fac(3); if (3 < 1) { else { return 3 * 2; rekursionen kommer upp public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1);

Evaluering System.out.println(fac(4)); if (4 < 1) { else { return 4 * 6; rekursionen kommer upp public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1);

Evaluering System.out.println( 24 ); rekursionen kommer upp public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1);

Sammanfattning av beräkningen System.out.println(fac(4)); fac(4) = 4 * fac(3) = 4 * 3 * fac(2) = 4 * 3 * 2 * fac(1) = 4 * 3 * 2 * 1 * fac(0) = 4 * 3 * 2 * 1 * 1 = 4 * 3 * 2 * 1 = 4 * 3 * 2 = 4 * 6 = 24 public static int fac(int n) { if (n < 1) { else { return n * fac(n- 1); n! = 1 if n<1 n (n 1)! if 1 apple n

Ett test program public class Fac { public static int fac(int n) { if (n == 0) { else { return n * fac(n- 1) ; public static void main(string[] args) { System.out.println("fac(1) = " + fac(1)); System.out.println("fac(4) = " + fac(4)); System.out.println("fac(20) = " + fac(20)); Utskrift: fac(1) = 1 fac(4) = 24 fac(20) = - 2102132736 umm Vad hände här? svar: värdet blev för stort. Obs. overflow har inget med rekursionen att göra.

Vi kan använda BigInteger import java.math.biginteger; public class BigFac { public static BigInteger fac(biginteger n) { if (n.equals(biginteger.zero)) { return BigInteger.ONE; else { return n.multiply(fac(n.subtract(biginteger.one))); public static void main(string[] args) { System.out.println("fac(1) = " + fac(new BigInteger("1"))); System.out.println("fac(4) = " + fac(new BigInteger("4"))); System.out.println("fac(20) = " + fac(new BigInteger("20"))); System.out.println("fac(50) = " + fac(new BigInteger("50"))); Utskrift: fac(1) = 1 fac(4) = 24 fac(20) = 2432902008176640000 fac(50) = 30414093201713378043612608166064768844377641568960512000000000000

Uppgift Skriv ett program som beräknar hur många nollor det finns i ett decimal tal. Idé: I ett negativ tal finns det like många nollor som i motsvarande positiva tal. Om talet är 0, finns det en nolla i talet. Om talet är positivt och < 10, finns det ingen nolla. I övriga fall, dvs. positivt och > 10 om talet mod 10 är 0, då finns det en nolla + nollorna i talet / 10 annars: nollorna i talet / 10

Lösning public class Z { public static int k(int n) { if (n < 0) { return k(0 - n); else if (n == 0) { else if (n < 10) { return 0; else if (n % 10 == 0) { return 1 + k(n / 10); else { return k(n / 10); public static void main(string[] args) { System.out.println("nollor(- 1050) = " + k(- 1050));

Uppgift Skriv en rekursiv metod som vänder om en sträng, dvs rev( Hello ) bör bli "olleh".

Uppgift Skriv en rekursiv metod som vänder om en sträng, dvs rev( Hello ) bör bli "olleh". public static String rev(string str) { if (str.length() == 0) { return str; else { return rev(str.substring(1)) + str.substring(0,1); Ofta går det att skriva om rekursionen som en iterativa metod men inte alltid.

Några animationer h"#://impedagog..com/wp/wp- content/uploads/2014/08/recursionelevator.gif h"#://i.imgbr.com/p1chi6u.gif h"#://media.giphy.com/media/vlng6lokeurfg/giphy.gif

Roligt med rekursion Vad räknar McCarthy s funktion m? m(n) = n 10 if n>100 m(m(n + 11)) if n apple 100 Samma i Java: public static int m(int n) { if (n > 100) { return n - 10; else { return m(m(n + 11));

McCarthy s funktion public class M { public static int m(int n) { if (n > 100) { return n - 10; else { return m(m(n + 11)); public static void main(string[] args) { for (int j=0; j<100; j++) { System.out.println("m(" + j + ") = " + m(j));

McCarthy s funktion public class M { public static int m(int n) { if (n > 100) { return n - 10; else { return m(m(n + 11)); public static void main(string[] args) { for (int j=0; j<100; j++) { System.out.println("m(" + j + ") = " + m(j)); Detta är McCarthy s 91 funktion. h"#://en.wikipedia.org/wiki/mccarphy_91_fbnction Varför blir det 91? Utskrift: m(0) = 91 m(1) = 91 m(2) = 91 m(3) = 91 m(4) = 91 m(5) = 91 m(6) = 91 m(7) = 91 m(8) = 91 m(9) = 91 m(10) = 91 m(11) = 91 m(12) = 91 m(13) = 91 m(14) = 91 m(15) = 91 m(16) = 91 m(17) = 91 m(18) = 91 m(99) = 91

Slutar beräkningen? Ibland blir input större inför rekursionen. t(n) = ( 1 if n =1 t(3 n + 1) if n is odd t(n/2) if n is even Samma i Java: public class T { public static int t(int n) { System.out.print(n + " "); if (n < 1) { System.exit(1); if (n == 1) { else if (n % 2 == 1) { return t(3 * n + 1); else { return t(n / 2); public static void main (String[] args) { t(integer.parseint(args[0])); Utskrift: $ javac T.java $ java T 125 125 376 188 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1 Koden var i upp vid 9232!

Slutar beräkningen? Ibland blir input större inför rekursionen. t(n) = ( 1 if n =1 t(3 n + 1) if n is odd t(n/2) if n is even Slutar beräkningen för alla utgångsvärden av n? Svar: ingen vet! Det är en open research question Vi kan testa litegrann men hur vet vi att räkningen slutar för alla input? (Bör göras med BigInteger.)

Flera animationer h"#s://i.chzbgu.com/maxw500/7732713984/h2e032a91/ h"#://d5lx5634mkgoi.cloud]ont.net/wp- content/uploads/2010/02/slide190.gif h"#://33.media.tbmblr.com/142251408fc0a2446612ef96e7c_e7/tbmblr_moltlz3owo1qz

Lite mera seriöst igen

Beräkna exp Att beräkna x n : Iterativt, idé x n = x x... x public static double power1(double x, int n) { double tmp = 1.0; for (int i=1; i<=n; i++) { tmp = tmp * x; return tmp; multiplicerar x in i tmp, n gånger. Rekursivt, idé x n (n 1) = x x public static double power2(double x, int n) { if (n == 0) { return 1.0; else { return x * power2(x,n- 1); gör samma sak. Samma algoritm!

Beräkna exp (forts) Bättre rekursion? Obs: x n = x n/2 x n/2 eller ännu bättre: x n =(x x) n/2 Mera precis: x 2 n = (x x) n x 2 n+1 = (x x) n x I Java: public static double power3(double x, int n) { if (n == 0) { return 1.0; else { if (n % 2 == 0) { return power3(x * x, n / 2); else { return power3(x * x, n / 2) * x; heltalsdivision, dvs blir heltal

Jämförelse power2(9,3.0) = 3.0 * power2(8,3.0) = 3.0 * 3.0 * power2(7,3.0) = 3.0 * 3.0 * 3.0 * power2(6,3.0) = 3.0 * 3.0 * 3.0 * 3.0 * power2(5,3.0) = 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * power2(4,3.0) = 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * power2(3,3.0) = 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * power2(2,3.0) = 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * power2(1,3.0) = 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * power2(0,3.0) = 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 3.0 * 1.0 = 19683.0 power3(9,3.0) = power3(4,9.0) * 3.0 = power3(2,81.0) * 3.0 = power3(1,6561.0) * 3.0 = power3(0,6561.0) * 6561.0 * 3.0 = 1.0 * 6561.0 * 3.0 = 19683.0 bättre algoritm! men vilken tar längre tid att beräkna?

Att mäta tid i Java I java.lang.system finns metoder: static long currenttimemillis() Returns the current time in milliseconds. static long nanotime() Returns the current value of the most precise available system timer, in nanoseconds. Exempel användning: long start = System.currentTimeMillis(); gör arbete long duration = System.currentTimeMillis() - start; System.out.println("Duration: " + duration + " ms");

Att mäta tid på power funktionerna public static void main(string[] args) { int reps = 10000; long start, duration; // test power1 start = System.currentTimeMillis(); for (int i = 0; i < reps; i++) { power1(2.0, 5000); duration = System.currentTimeMillis() - start; System.out.println("Duration1: " + duration + " ms"); // test power3 start = System.currentTimeMillis(); for (int i = 0; i < reps; i++) { power3(2.0, 5000); duration = System.currentTimeMillis() - start; System.out.println("Duration3: " + duration + " ms"); $ java Pow Duration1: 93 ms Duration3: 3 ms

Hitta element i array Hur kollar man om ett element finns i en array?

Hitta element i array Hur kollar man om ett element finns i en array? Enkel kod: public static boolean lookup(int k,int[] arr) { for (int i=0; i<arr.length; i++) { if (arr[i] == k) { return true; return false; om arrayn sorterad går det att göra mycket snabbare!

Binärsökning Exempel: Kolla om värdet 5 finns i arrayn? 0 1 2 5 8 11 12 14 16 18 22 24 Idé: Inspektera elementet i mitten av arrayn: 0 1 2 5 8 11 12 14 16 18 22 24 Är mitten elementet det vi söker? Om mitten elementet är mindre kan vi kasta bort den högra sidan. 0 1 2 5 8 11 vi vet ju att arrayn är sorterad. och så kan vi upprepa sägen ovan tills arrayn är tom.

Binärsökning (forts) Som rekursiv Java kod: public static boolean bsearch1(int k,int[] arr,int b,int e) { // System.out.println("b,e = " + b + "," + e); if (e <= b) { return false; int i = (b + e) / 2; // mitten if (arr[i] == k) { return true; else if (arr[i] < k) { return bsearch1(k,arr,i+1,e); else /* k < arr[i] */ { return bsearch1(k,arr,b,i); public static boolean bsearch(int k,int[] arr) { return bsearch1(k,arr,0,arr.length);

Binärsökning (forts) Samma som iterativa kod: public static boolean bsearchit(int k,int[] arr) { int b = 0; int e = arr.length; while (b < e) { int i = (b + e) / 2; // mitten if (arr[i] == k) { return true; else if (arr[i] < k) { b = i+1; else /* k < arr[i] */ { e = i; return false;

Fibonacci En känd rekursiv funktion: fib(n) = ( 0 if n =0 1 if n =1 fib(n 1) + fib(n 2) if 2 apple n Värden: Som bild: fib(0) = 0 fib(1) = 1 fib(2) = 1 fib(3) = 2 fib(4) = 3 fib(5) = 5 fib(6) = 8 fib(7) = 13 fib(8) = 21 fib(9) = 34

Fibonacci Rekursion leder inte alltid till bra kod! I Java: public static int fib(int n) { if (n < 2) { return n; else { return fib(n- 1) + fib(n- 2); Flera rekursiva anrop beräknar samma sak: fib(6) fib(5) fib(4) fib(4) fib(3) fib(3) fib(2) fib(3) fib(2) fib(2) fib(1) fib(2) fib(1) fib(1) fib(0) fib(2) fib(1) fib(1) fib(0) fib(1) fib(0) fib(1) fib(0) fib(1) fib(0)

Iterativ version av Fibonacci? Rekursion leder inte alltid till bra kod! I Java: public static int fib(int n) { if (n < 2) { return n; else { return fib(n- 1) + fib(n- 2); Uppgift: skriv en iterativ version av Fibonacci.

Rekursion i typerna En annan form av rekursion: Drawable3D är rekursiv genom typerna public interface Drawable3D { public Drawable3D rotate(double xy_angle, double yz_angle); public void draw(graphics g, int width, int height); public Drawable3D translate(double x, double y, double z); Man kan skriva: public class Many3D implements Drawable3D {... private Many3D p1; private Many3D p2; Oändligt? Nej, det kan ju vara null.

Iterativ eller rekursiv? Iterativ kod är snabbare, speciellt i Java men vissa algoritmer går inte att skriva som iteration. nja, det går nog, men det kan vara mycket svårt! Uppgift: implementera QuickSort https://www.youtube.com/watch?v=ywwby6j5gz8

Uppgift: implementera QuickSort public static void swap(int[] array, int i, int j) { int a_i = array[i]; int a_j = array[j]; array[i] = a_j; array[j] = a_i; flyttar alla element < pivot till vänster, resten till höger public static int partition(int[] array, int pivot, int b, int e) { while (b < e) { if (array[b] < pivot) { b = b+1; else { swap(array,b,e-1); e = e-1; return b; byter plats på två element returnerar gränsen mellan < och >= element

Uppgift: implementera QuickSort slutar genast ifall det finns färre än två element, för då är vi färdiga public static void qsort(int[] array, int b, int e) { int nelements = e - b; if (nelements < 2) { return; int pivot = array[b]; int split = partition(array,pivot,b+1,e); swap(array,b,split-1); qsort(array,b,split-1); qsort(array,split,e); flyttar pivot elementet till mitten sorterar rekursivt båda partitionerna väljer en pivot arrangerar om elementen