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 iteratifRekursif 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= 244! = 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 programKecepatan 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, … .
nBarisan 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 stringPanjang 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