Rekursif Algoritma Struktur data

  Rekursif

Rizki Muliono,M.Kom

Learning Outcomes

  Pada akhir pertemuan ini, diharapkan mahasiswa akan mampu: 

Menjelaskan defnisi rekursif

  

Menerapkan rekursif dalam pembuatan program

   Membedakan rekursif dan iteratif

   Defnisi rekursif

   Deklarasi rekursif

   Penggunaan rekursif

   Analisa rekursif dan iterasi

  Outline Materi

Defnisi Rekursif

   Method yang memanggil dirinya sendiri

   Berguna untuk teknik pemrograman

  

Lebih memudahkan pemecahan masalah

tertentu

   Contoh:

  Faktorial 0! = 1; n! = n x (n – 1)!; n > 0

   Memerlukan kondisi penghentian (stopping condition atau base case)

   Contoh deklarasi rekursif: public static long factorial( int n) { if (n==0) // stopping condition / base case return 1; else return n * factorial(n-1); // recursive call }

   Pemanggilan factorial (diri sendiri)  rekursif

  

Dipanggil sampai mencapai kondisi n == 0

(stopping condition atau base case)

  Deklarasi Rekursif

  Penggunaan Rekursif

Penggunaan Rekursif

  return 1 return 1 * factorial(0) return 2 * factorial(1) return 3 * factorial(2) return 4 * factorial(3) factorial(4)

  Step 0: executes factorial(4) Step 1: executes factorial(3)

  Step 2: executes factorial(2) Step 3: executes factorial(1)

  Step 4: executes factorial(0) Step 5: return

  1 Step 6: return

  1 Step 7: return

  2 Step 8: return

  6 Step 9: return

  24

Penggunaan Rekursif

  

Faktorial lebih baik menggunakan loop

int hasil = 1; if (bil>1) { for ( int i=2; i<=bil; i++) hasil *= i; }

   Faktorial baik dalam merepresentasikan rekursif

Penggunaan Rekursif

  

  Fibonacci: Inde 0 1 2 3 4 5 6 7 8 9 1

  1 x

  1

  

  Seri 0 1 1 2 3 5 8 1

  2

  3

  5

  8 Dimulai dari 0 dan 1

  3

  1

  4

  5

  9

  

  Bilangan berikutnya penjumlahan dari 2 bilangan sebelumnya

  

  fb(0) = 0 fb(1) = 1 fb(index) = fb(index – 2) x fb(index – 1); index > =2

  Penggunaan Rekursif

  Penggunaan Rekursif

   Palindrom: kata, frasa, bilangan, atau kalimat yang dibaca sama dari 2 arah pembacaan

   Contoh:

  ◦ Civic

  ◦ Level

  ◦ Rotator

  ◦ Was it a rat I saw ◦ 58285

  ◦ 20-02-2002

  Penggunaan Rekursif

  Penggunaan Rekursif

  Penggunaan Rekursif

Penggunaan Rekursif

   Method isPalindrome pertama mengecek apakah string tersebut palindrom

  

Method isPalindrome kedua mengecek

apakah substring tersebut palindrom

   Teknik mendeklarasikan method bantuan untuk rekursif  recursive helper method

   Berguna untuk string dan array

   Rekursif:

  ◦ Bentuk alternatif kontrol program ◦ Repetisi tanpa loop ◦ Memanggil methodnya sendiri ◦ Memerlukan pernyataan seleksi (if) untuk base case/stopping condition ◦ Memerlukan memori lebih banyak ◦ Waktu eksekusi lebih lambat ◦ Terkadang lebih jelas, sederhana dibandingkan iteratif

   Iteratif:

  

◦ Merupakan struktur kontrol (fundamental dari bahasa pemrograman)

◦ Spesifkasi loop body

  Dikontrol oleh loop-control-structure ◦ Memori lebih sedikit dan waktu proses lebih cepat

  

Permasalahan yang dapat diselesaikan oleh

rekursif pasti bisa diselesaikan oleh iteratif

  Rekursif vs Iteratif

Did You Know?

   Infnite recursion (rekursif tak terhingga) terjadi jika tidak ada stopping condition atau base case

   Contoh pada Faktorial public static long factorial( int n) { return n * factorial(n-1); // recursive call }

   Menyebabkan StackOverfowError

   Solusi if (n==0) // stopping condition / base case return 1;

Advanced Learning

   Tower of Hanoi: contoh rekursif klasik

   Mudah diselesaikan dengan rekursif

   Terdapat 3 menara (tower) dan beberapa cakram (disk) dengan ukuran berbeda

   Disk atas harus lebih besar daripada disk bawah

   Semua disk berawal dari tower pertama

   Hanya 1 disk yang boleh dipindahkan dalam sekali waktu

   Semua disk harus dipindahkan ke tower akhir

  Advanced Learning

  Advanced Learning

  Advanced Learning

  Fungsi Rekursif (Berulang) Rekursif VS Iterasi

Defnisi

   Recursive = Berulang

   Recursive function = fungsi rekirsif = fungsi yang berulang

   di dalam fungsi tersebut dia memanggil dirinya sendiri

Fungsi Rekursif

   Fungsi rekursif:

Di dalamnya terdapat pernyataan yang memanggil

dirinya sendiri.

   Berguna untuk memecahkan masalah yang dapat didefnisikan secara rekursif pula.

   n faktorial atau n! = n * n-1 * n-2 * …. * 3 * 2 * 1, dan didefniskan bahwa 0! = 1

   Contoh:

   4! = 4 * 3 * 2 * 1

  3! = 3 * 2 * 1

   4! = 4 * 3!

   n! = n * (n-1)! 

  

Faktorial (n) atau n! didefnisikan sebagai berikut :

jika n = 0, n! = 1 jika n > 0, n! = n * (n-1)! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1* 0! 0! = 1 Jadi: 4! = 4*3*2*1= 24

  4! = 4*3! = 4*3*2! = 4*3*2*1! = 4*3*2*1 = 24

  // iteratif dekremental long faktorialIteratifDec(long n) mulai long i, faktorial = 1; for(i=n; i>=1; i--) faktorial *= i; return faktorial; selesai tutup

  4! = 1*2*3*4 = 24

  // iteratif inkremental long faktorialIteratifInc(long n){ mulai long i, faktorial = 1; for(i=1; i<=n; i++) faktorial *= i; return faktorial; selesai tutup

  Fungsi Iteratif

Fungsi Rekursif

  

Contoh perhitungan 5 faktorial

  5! (5 * 4!) (5 * (4 *3!)) (5 * (4 * (3 * 2!))) (5 * (4 * (3 * (2 * 1!)))) (5 * (4 * (3 * (2 * (1 * 0!))))) (5 * (4 * (3 * (2 * (1 * 1))))) (5 * (4 * (3 * (2 * 1)))) (5 * (4 * (3 * 2))) (5 * (4 * 6 )) (5 * 24) 120

Fungsi Rekursif

   Fungsi rekursif mempunyai dua komponen yaitu:

  ◦ Base case:

  Mengembalikan nilai tanpa melakukan pemanggilan rekursi berikutnya.

  Rekursi berakhir jika base case dijumpai/dipenuhi

  ◦ Recursion call / Reduction step:

  Memanggil fungsi rekursif di dalam fungsi rekursif di atas Menghubungkan sebuah fungsi rekursif dengan fungsi rekursif di dalamnya Biasanya memiliki keyword return untuk mengembalikan nilai ke fungsi yang memanggilnya

Fungsi Rekursif

   Fungsi faktorial

  ◦ Base case: n = 0

  ◦ Reduction step: f(n) = n * f(n-1)

  // rekursif long faktorialRekursif(long n) mulai if(n==0) return (1); else return(n * faktorialRekursif(n-1)); selesai tutup

   Contoh:

  • Faktorial - Rekursif
  • Faktorial - Iteratif // dekremental
  • Faktorial - Rekursif
  • Faktorial - Iteratif // dekremental

  long faktorial(long n) mulai if(n==0) return (1); else return(n*faktorial(n-1)); selesai tutup

  long faktorial(long n) mulai if(n==0) return (1); else return(n*faktorial(n-1)); selesai tutup

  long faktorial(long n) mulai long i, faktorial = 1; for(i=n; i>=1; i--) faktorial *= i; return faktorial; selesai tutup

  long faktorial(long n) mulai long i, faktorial = 1; for(i=n; i>=1; i--) faktorial *= i; return faktorial; selesai tutup Rekursif vs Iteratif

Rekursif

Iteratif

Rekursif

Iteratif

  Pengulangan tanpa henti jika kondisi pengulangan selalu benar

  Rekursif vs Iteratif

  Terbaca kurang jelas, model kurang dekat dengan masalah (contoh: faktorial, fbonacci)

  Biaya proses lebih rendah (kebutuhan memori lebih kecil & kerja prosesor lebih rendah) karena proses pengulangan berada dalam satu fungsi

  Pengulangan tanpa henti jika kondisi pengulangan selalu benar

  Pengulangan berhenti saat kondisi pengulangan bernilai salah (false)

  Pengulangan dengan struktur repetisi (for/while)

  Terbaca kurang jelas, model kurang dekat dengan masalah (contoh: faktorial, fbonacci)

  Biaya proses lebih rendah (kebutuhan memori lebih kecil & kerja prosesor lebih rendah) karena proses pengulangan berada dalam satu fungsi

  Pengulangan dengan struktur seleksi (if-else) dan pemanggilan fungsi (dirinya sendiri) -> rekursi

  Pengulangan berhenti saat base

  Biaya proses lebih tinggi dengan pemanggilan banyak fungsi (butuh memori lebih besar & kerja prosesor lebih tinggi)

  dijumpai/dipenuhi (tidak konvergen terhadap base case)

  base case tidak pernah

  (konvergen terhadap base case) Pengulangan tanpa henti jika

  case dijumpai/dipenuhi

  Pengulangan berhenti saat base

  Pengulangan dengan struktur seleksi (if-else) dan pemanggilan fungsi (dirinya sendiri) -> rekursi

  Biaya proses lebih tinggi dengan pemanggilan banyak fungsi (butuh memori lebih besar & kerja prosesor lebih tinggi)

  dijumpai/dipenuhi (tidak konvergen terhadap base case)

  base case tidak pernah

  (konvergen terhadap base case) Pengulangan tanpa henti jika

  case dijumpai/dipenuhi

  Pengulangan dengan struktur repetisi (for/while) Pengulangan berhenti saat kondisi pengulangan bernilai salah (false)

Kekurangan Rekursi

   Meskipun penulisan program dengan cara

rekursif bisa lebih jelas dan pendek, namun

fungsi rekursif memerlukan :

  ◦ Memori yang lebih banyak untuk mengaktifkan stack (memori yang digunakan untuk pemanggilan fungsi).

  ◦ Waktu lebih lama untuk menjejaki setiap rekursi melalui stack.

  Apakah stack ?

   Secara umum, hanya jika :

  ◦ Penyelesaian sulit dilaksanakan secara iteratif

  ◦ Efsiensi dengan cara rekursif masih memadai ◦ Efsiensi bukan masalah dibandingkan dengan kejelasan logika program

  

◦ Tidak mempertimbangkan faktor penghematan memori

dan kecepatan eksekusi program

  Kecepatan kerja dan penghematan memori (iteratif)

VS

  Perancangan logika yang baik (rekursif) Kapan Rekursi?

Bilangan Fibonacci

   Urutan bilangan 0, 1, 1, 2, 3, 5, 8, 13 … disebut bilangan Fibonacci.

   Hubungan antara satu angka dengan angka berikutnya didefnisikan secara rekursif sebagai berikut :

  ◦ Fib(n) = n, jika n = 0 atau 1

  ◦ Fib(n) = Fib(n-2) x Fib(n-1) , jika n >= 2

   Misalkan jika ditanya berapa suku ke-4 dari barisan fbonachi?

   n = 4 fbo(4) =

  = fbo(3) x fbo(2) = ( fbo(2) x fbo(1)) x (fbo(1) x fbo(0)) = ( (fbo(1) x fbo(0)) x 1) x (1 x 0) = ( (1 x 0) x 1) x

  1 = ( 1 x 1) x

  1 = 2 x

  1 = 3

Bilangan Fibonacci int Fib(int n) int Fib(int n) mulai mulai int f; int f; if(n==0) if(n==0) f = 0; f = 0; else if(n==1) else if(n==1) f = 1; f = 1; else else f = Fib(n-2) + Fib(n-1); f = Fib(n-2) + Fib(n-1); return f; return f; selesai selesai tutup tutup

  Fungsi fb() di atas ditulis secara rekursif dan disebut Fungsi fb() di atas ditulis secara rekursif dan disebut sebagai slow_Fib() sebagai slow_Fib() Tulislah fast_Fib() jika menggunakan iterasi.

  Tulislah fast_Fib() jika menggunakan iterasi.

  FIB (4) FIB (3) FIB (2) FIB (2) FIB (1) FIB (1) FIB (0)

   Contoh : Skema fbonacci jika N=4

  Bilangan Fibonacci + +

  • + +

Latihan

   Implementasikan algoritma rekursi untuk fungsi fbonaci dan rekursif!

  Recursif faktorial C++

   #include <iostream>

   int main()

       cout << n << "! = "<< rekursifaktorial(n) << endl;

    

       int n = 4;

    

       int x;

   {

   }

   using namespace std;

           return f * rekursifaktorial(f - 1);

       else

           return 1;

       if (f == 0)

   { 

   long rekursifaktorial(int f)

  

Recursif faktorial C++

Recursif faktorial C++

   n = 9;

   cout << n << "! = “ << rekursifaktorial(n) << endl;

   cout<<"Masukan Angka yang akan difaktorialkan : ";

   cin>>x;

  

cout << x <<"! = " << rekursifaktorial(x) <<endl;

    

       return 0;

   }

  Faktorial C++

Referensi

  

Introduction to Java Programming. 7ed. Liang.

  2009. ch 20  Java Software Solutions. 5ed. Lewis & Loftus.

  2007. ch 11  Fibonacci.

   Palindrome.

   Towers of Hanoi.

  ◦

  ◦

  ◦

  ◦

  Rekursif II

Defnisi Rekursif

  Ada kalanya kita mengalami kesulitan untuk mendefnisikan suatu obyek secara

  eksplisit .

  Mungkin lebih mudah untuk mendefnisikan obyek tersebut dengan menggunakan dirinya sendiri. Ini dinamakan sebagai proses rekursif .

  Kita dapat mendefnikan barisan , fungsi dan himpunan secara rekursif.

Barisan yang didefnisikan secara rekursif

  Contoh: Barisan bilangan pangkat dari 2 n

a = 2 untuk n = 0, 1, 2, … .

n

  Barisan ini dapat didefnisikan secara rekursif : a = 1 a = 2a untuk n = 0, 1, 2, … nx1 n

  

Langkah-langkah untuk mendefnisikan barisan secara

rekursif : 1.

  Langkah basis : Spesifkasi anggota awal.

Contoh barisan yang didefnisikan secara rekursif

  n

Berikan defnisi rekursif dari a =r , dengan

n r N, r≠0 dan n bilangan bulat positif.

  Solusi: Defnisikan a =r =1 . dan a =r a untuk n = 0, 1, 2, … nx1 n

Fungsi yang didefnisikan secara rekursif

  Langkah-langkah untuk mendefnisikan fungsi dengan domain bilangan cacah :

  1. Langkah basis : Defnisikan nilai fungsi pada saat nol.

  2. Langkah rekursif : Berikan aturan untuk

  mencari nilai fungsi untuk setiap bilangan bulat berdasarkan nilai fungsi pada bilangan bulat yang lebih kecil.

  Defnisi seperti itu disebut rekursif atau defnisi induktif .

  Contoh fungsi yang didefnisikan secara rekursif f(0) = 3 f(n x 1) = 2f(n) x 3 Maka f(0) = 3 f(1) = 2f(0) x 3 = 2 3 x 3 = 9 f(2) = 2f(1) x 3 = 2 9 x 3 = 21 f(3) = 2f(2) x 3 = 2 21 x 3 = 45 f(4) = 2f(3) x 3 = 2 45 x 3 = 93

  Contoh fungsi yang didefnisikan secara rekursif (2)

  Bagaimana kita dapat mendefnisikan

fungsi faktorial f(n) = n! secara rekursif?

  f(0) = 1 Karena (nx1)! = n! (nx1) maka f(n x 1) = (n x 1)f(n) f(0) = 1 f(1) = 1 f(0) = 1  1 = 1 f(2) = 2 f(1) = 2  1 = 2 f(3) = 3 f(2) = 3  2 = 6

   6 = 24 f(4) = 4 f(3) = 4

Contoh fungsi yang didefnisikan secara rekursif (3)

  Bagaimana kita dapat mendefnisikan fungsi secara rekursif?

   

  

n k k

  

) a n f (

Fibonacci

  f = 0, f

  1

  = 1 f

  n

  = f

  n-1

  x f

  n-2

  , n=2,3,4,… Langkah-langkah dalam mendefnisikan suatu himpunan secara rekursif:

  Contoh terkenal: Bilangan

  f = 0 f 1 = 1 f 2 = f 1 x f = 1 x 0 = 1 f 3 = f 2 x f 1 = 1 x 1 = 2 f 4 = f 3 x f 2 = 2 x 1 = 3 f 5 = f 4 x f 3 = 3 x 2 = 5 f 6 = f 5 x f 4 = 5 x 3 = 8 Tunjukkan bahwa untuk n  3, f

  n

  < 

  n

  dengan  = (1x√5)/2.

  Spesifkasi koleksi awal dari anggota 2.

  Langkah rekursif : Mendefnisikan aturan konstruksi anggota baru dari anggota yang telah diketahui

  Himpunan yang didefnisikan secara rekursif

Contoh himpunan yang didefnisikan secara rekursif

  Misalkan S didefnisikan secara rekursif oleh:

  3  S (xxy)  S jika x  S dan y  S Maka S adalah himpunan bilangan bulat positif yang habis dibagi 3.

  Bukti: Misalkan A himpunan yang beranggotakan semua bilangan bulat positif yang habis dibagi 3.

  Untuk membuktikan bahwa A = S, harus ditunjukkan A  S and S  A.

  

bahwa setiap bilangan bulat positif yang habis dibagi 3

ada di S (dengan menggunakan induksi matematika ).

  Contoh himpunan yang didefnisikan secara rekursif (2) Misalkan P(n): proposisi “3n anggota S”.

   S 2.

  1. Langkah basis: P(1) benar, karena 3 .

  Langkah induktif: Asumsikan P(k) benar, yaitu 3k  S. Akan ditunjukkan P(kx1) juga benar, yaitu 3(kx1)  S Karena 3k dan 3 , berdasarkan

   S  S defnisi rekursif dari S, 3kx3 = 3(kx1) juga ada di S.

  3. Konklusi: Jadi, setiap bilangan bulat positif yang habis dibagi 3 ada di S.

  Kesimpulan dari bagian I adalah A  S .

  Contoh himpunan yang didefnisikan secara rekursif (3)

   A dengan menggunakan defnisi rekursif dari S.

  Langkah basis: Akan ditunjukkan setiap anggota awal S ada di A.

  Karena 3 habis dibagi 3 maka 3  A.

  Langkah rekursif:

Akan ditunjukkan bahwa setiap bilangan bulat yang dibangun

dengan mengunakan langkah rekursif juga merupakan anggota A, yaitu (xxy)

   A jika x,y  S (yang diasumsikan  A).

Jika x dan y keduanya di A, maka 3 | x dan 3 | y. Akibatnya, 3 |

(x x y).

  Kesimpulan dari bagian II adalah S .

   A Jadi, secara keseluruhan, berlaku A = S.

Induksi Struktural

  Dalam membuktikan hasil-hasil yang berkaitan dengan himpunan yang didefnisikan secara

rekursif , akan lebih mudah apabila digunakan

suatu bentuk induksi matematika yang disebut induksi struktural .

  Langkah-langkah dalam induksi struktural: 1.

  Langkah basis : Menunjukkan bahwa hasil yang akan dibuktikan berlaku untuk semua anggota awal.

  Menunjukkan bahwa jika hasil yang akan dibuktikan berlaku untuk anggota-anggota yang digunakan untuk membangun anggota baru, maka hasil tersebut juga berlaku untuk anggota yang baru dibangun.

  Himpunan string atas alfabet

  Himpunan string  atas alfabet  dapat didefnisikan secara

  • rekursif oleh: 1.

  Langkah basis :  ( adalah string kosong yang tidak memuat simbol)  

  • 2.

  Langkah rekursif :

  Jika w dan x     , maka wx   Contoh: Jika  = {0,1} maka string yang merupakan anggota 

  • adalah:

    yang didefinisikan sebagai anggota  dalam langkah basis,

  0 dan 1 yang dibentuk dalam langkah rekursif pertama,

  • 00, 01, 10, dan 11 yang dibentuk dalam langkah rekursif

  • >kedua, dst

  • , maka w.  = w, dengan  string kosong 2.
  • dan w
  • dan x   , maka

  1 . w

  w 1 w 2

  Konkatenasi dari w 1 = meng dan w 2 = apa adalah

  w 2 Contoh:

  seringkali ditulis sebagai w 1

  Himpunan string atas alfabet (2) w 1 . w 2

  2 ) x

  2

x) = (w

  Konkatenasi Sebagai operasi kombinasi dari dua string, konkatenasi didefnisikan secara rekursif sebagai: 1.

  1 . (w

  w

  2  

  1  

  Langkah rekursif : Jika w

  Langkah basis : Jika w  

  = mengapa

  

Himpunan string atas alfabet

(3) Panjang string

  Panjang dari string w, l (w) dapat didefnisikan secara rekursif oleh:

  l () = 0, l ( w x ) = l ( w ) x 1 jika w dan x    .

  • Gunakan induksi struktural untuk membuktikan bahwa

  l x y l x l y ( ) = ( ) x ( ).

Perluasan induksi

  Induksi matematika dapat diperluas untuk

membuktikan hasil-hasil mengenai himpunan

yang memiliki sifat terurut dengan baik .

  Contoh: himpunan N x N

  

Contoh perluasan induksi

Misalkan didefnisikan secara rekursif untuk (m,n)

   N x N oleh dan Tunjukkan bahwa untuk setiap (m,n) n m a

  , ,

   a

    

       

    , jika , dan jika

  1 1 , ,

  1 , n n a m n a a n m n m n m

  ) 2 / 1 ( ,

     n n m a n m

  Rekursif

Deret Fibonanci

   Proses yang memanggil dirinya sendiri. 

  Merupakan suatu fungsi atau prosedur  Terdapat suatu kondisi untuk berhenti.

  Rekursif

Faktorial

  

  Konsep Faktorial n! = n(n-1)(n-2)…1

  

  Dapat diselesaikan dengan

  ◦ Cara Biasa

  ◦ Rekursif

   Int Faktorial(int n)

   {

   if (n<0) return -1 ;

   else if (n>1)

   {

   S = 1 ;

  

for(i=2 ;i<=n;ixx) S = S * n ;

   return S ;

   }

   else return 1 ;

   }

  

Faktorial : Cara Biasa

   Int Faktorial(int n)

   { if (n<0) return -1 else if (n>1) Return (n*Faktorial(n-1))

  Else Return 1 ; 

  }

Faktorial dengan Rekursif

Deret Fibonacci

  

  Leonardo Fibonacci berasal dari Italia 1170- 1250

  

  Deret Fibonacci f , f ,… didefinisikan secara

  1

  2

  rekursif sebagai berikut : f = 1

  1

  f = 2

  2

  f = f + f for n > 3

  n n-1 n-2 

  Deret: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597,…

  

  procedure fab(n)

   

  if n=1 then return 1

   

  if n=2 then return 2

  

  return (fab(n-1) x fab(n-2))

  

  end

  Deret Fibonacci

Rekursif Tail

   Jika pernyataan terakhir yang akan dieksekusi berada dalam tubuh fungsi

   Hasil yang kembali pada fungsi tsb bukanlah bagian dari fungsi tersebut.

   Tidak memiliki aktivitas selama fase balik.

Rekursif Tail : Faktorial()

  F(4,1) = F(3,4) Fase awal F(3,4) = F(2,12) F(2,12) = F(1,24)

F(1,24) = 24 Kondisi Terminal

  24 Fase Balik Rekursif Lengkap

Latihan

   Algoritma BinRec(n)

  ◦

//input : Bilangan desimal integer positif n

  ◦ //output : Jumlah digit biner yang dinyatakan dengan n

  If (n=1) return 1 Else return BinRec(  n/2 ) x 1