You are on page 1of 25

TEKNIK REKURSIF

Salah satu keistimewaan yang dimiliki Pascal adalah adanya proses rekursif. Sifat rekursif ini dimiliki oleh beberapa statemen Pascal Rekursifberarti suatu proses yang bisa memanggil dirinya sendiri. Dalam rekursi sebenamya terkandung pengertian prosedur atau fungsi. Perbedaannya adalah bahwa rekursi bisa memanggil ke dirinya sendiri, tetapi prosedur atau fungsi harns dipanggillewat pemanggil prosedur atau fungsi. Rekursi merupakan teknik pemrograman yang penting. dan beberapa bahasa pemrograman modern mendukung keberadaan proses rekursi ini.

Dalam prosedur atau fungsi, pemanggilan ke dirinya sendiri bisa berarti proses berulang yang tidak bisa diketahui kapan akan berakhir. Dalam pemakaian sehari-hari, rekursif merupakan teknik pemrograman yang berbeda guna untuk digunakan pada pekeIjaan pemrograman dengan mengekspresikannya ke dalam suku-suku dari program lain dengan menambahkan langkah-langkah sejenis.

Contoh paling sederhana dari proses rekursif adalah proses menghitung nilai faktoral dari bilangan bulat positif dan mencari deret Fibonnaci dari suatu bilangan bulat.

Nilai faktorial, secara rekursif dapat ditulis sebagai :

Ot = 1

Nl = N x (N - I)!

untuk N> 0

23

yang seeara notasi pemrograman bisa ditulis sebagai :

FAKTORIAL(O) ;;;; 1

FAKTORIAL(N) = N * FAKTORIAL(N - 1)

1) 2)

Persamaan 2) di atas merupakan eontoh hubungan rekurens (recurrence relation), yang berarti bahwa nilai suatu fungsi dengan argwnen tertentu bisa dihitung dari fungsi yang sam dengan argumen yang Iebih kecil Persamaan 1) yang tidak bersifat rekursif, disebut nilai awal. Setiap fungsi rekursi paling sedikit mempunyai 1 (satu) nilai awa1; jika tidak, fungsi tersebut tidak bisa dihitung secara eksplisit, I

Bilangan Fibonacci bisa didefmisikan berdasar deret integer tak terhingga sebagai berikut :

1 1 2 3 5 8 12 13 21 34 55 89 ...

Dari deret di atas bisa dilihat bahwa bilangan ke N (N) 2) dalam deret bisa dicari dari 2 (dua) bilangan sebelumnya yang terdekat dengan bilangan ke Nm yaitu bilangan ke (N-I) dan bilangan ke (N-2). Sehingga jika ABO(N) menunjukkan bilangan Fibonacci suku ke N, maka FlBO(N) bisa dihitung berdasar hubungan rekurens :

FIBO(N) = FlBO(N - 1) + FIBO(N - 2)

Karena FlBO(N) ditentukan oleh dua nilai yang berbeda dengan argumen yang Iebih kecil, maka untuk meneari bilangan fibonacci diperlukan 2 (dua) nilai awal, yaitu :

FIBO(1) = 1 dan

ABO(2) - 2

2.1. PROSES REKURSIF

Untuk memahami proses rekursif yang teIjadi dalam sebuah fungsi rekursif, perbatikan contoh sederhana di bawah Uti. Contoh di bawah ini menyajikan satu fungsi untuk menghitung harga faktoral suatu integer seperti yang telah dijelaskan di alas.

Dari definisi di atas, bisa dibuat fungsi F AKT sebagai berikut :

{ *********************************************************

* Fungsi untuk menghitung bilangan faktorial dengan eara rekursif * ********************************************************* } function F AKT(N : integer) : integer;

begin

if N ;;;; 0 then FAKT :~ 1 else

FAKT := N * FAKT(N - 1)

end;

Program 2.1. Fakiorial dengan cara rekursif

24

Dari fungsi di atas bisa dilihat bahwa FAKT(N) bisa dihitung dari FAKT (N-I), dimana FAKT(N-l) bisa dihitung dari FAKT(N-2) dan seterusnya. Dengan demikian, fungsi eli atas untuk N = 6 bisa kita lacak cara kerjanya, yaitu seperti terlihat pada Gambar 2.1.

Perhatikan bahwa untuk menghitung F AKT(N), maka fungsi hams memanggil nilai F AKT(N-I) yang telah diperoleh. Demikian juga untuk menghitung nilai FAKT(N -I), fungsi harus memanggil nilai F AKT(N - 2) dan seterusnya. Notasi F AKT(N -1), yang digunakan untuk memanggil nilai fungsi sebelumnya, sering disebut dengan pemanggil rekursif atau recursion call. Dalam ilustrasi di atas, pemanggil rekursi ditunjukkan dengan tanda anak panah. Sarna halnya dengan prosedur atau fungsi yang lain, maka dalam rekursi pasti ada pemanggil rekursi,

.Dengan eara yang sama, bisa dilihat fungsi FlBO untuk menghitung bilangan Fibonacci pada suatu suku ke N, yaitu seperti yang tersaji dalam Program 2.2. Pelacakan fungsi FIBO di atas untuk N = 6 adalah seperti pada Gambar 2.2.

FAKT(6) = 6 * FAKT(5) t

I FAKT(5) = 5 * FAKT(4) l'

I FAKT(4) = 4 * FAKT(3) .1'

I FAKT(3) = 3 * FAKT(2)

t

I F AKT(2) = 2 * FAKT(1) t

I FAKT(1) = 1 * FAKT(O)

nil.Tal

31 aw

Gombar 2.1. llustrasi fungsi F AKT dengan proses rekursif.

FIBO(6) = FIBO(5) + FlBO(4)

,....----Jt t

I

FIB0(5) = FIBO(4) + FIBO(3)

,....----J1' l'

I I

FIBO(4) = FIBO(3) + ABO(2)

I' n;11 awal

FIBO(3) = FlBO(2) + FIBO(l)

nilai i al . taT al

ai aw m 1 aw

Gambar 2.2. llustrasi fungsi FIBO dengan proses rekursif.

25

{ ********************************************************** * Prosedur untuk menghitung bilangan Fibonacci dengan earn rekursif * ************************************************************

function FIBO(N : integer) : integer,

begin

if (N = 1) or (N = 2) then FIBO := 1

else

FIBO(N) := FIBO(N - 1) + FIBO(N - 2)

end;

Program 2.2. Deret Fibonacci dengan cara rekursif.

2.2. TEKNIK REKURSIF DAN TEKNIK ITERATIF

Dalam beberapa hal, rekursi kurang efisien dibanding proses iterasi. Bandingkan fungsi FIBO di atas dengan fungsi di bawah ini yang juga digunakan untuk menghitung bilangan Fibonacci, tetapi dilaksanakan dengan eara iterasi.

{ ********************************************************

* Fungsi untuk menghitung bilangan Fibonacci dengan cara iteasi * ********************************************************* }

function FIBO_ITER(N : integer) : integer, var F, akhir, Bantu, 1 ; .Integer

begin

1 := 1; F := 1; akhir := 0; if N = 0 then F := 0; while I <> N do

begin

Bantu := F; I :;;:: I + 1; F := F + Akhir:

Akhir := Bantu end;

FIBO_ITER := F

end;

Program 23. Deret Fibonacci dengan cara iterasi.

26

Dalam contoh pertama (fungsi FIBO yang menggunakan proses rekursif), suatu bilangan pada suku ke N akan diperoleh melalui hubungan rekurens. Sebaliknya, cara rekursif seperti di atas adalah kurang nyata, karena ada 2 (dua) pemanggil rekursif dillruti yang lain Meskipun demikian, eara rekursif di alas menjadi terla1u jelek, karena kedalaman pemanggil rekursif sangat diperlukan dan juga karena pengulangan penghitungan dart suatu hasil yang sebenarnya telah dihitung. Sebagai contoh, AB0(6) memerlukan FIB 0(5), yang selanjutnya memerlukan FIBO(4), FIBO(3) dan seterusnya

Dalam beberapa situasi, pemecahan secara rekursif dan secara iteratif mempunyai keuntungan dan kekurangan yang bisa saling dipeIbandingkan. Adalah cukup sulit untuk menentukan mana yang paling sederhana, paling jelas, paling efisien dan paling mudah dibanding yang lain. Bisa ditambahkan, pemilihan cara iteratif maupun eara rekursif boleh dikatakan merupakan kesenangan seorang programer sesuai dengan kesanggupan dan eita rasanya.

2.3. MENYUSUN PERMUTASI

Contoh lain dart proses rekursif yang akan disajikan adalah untuk menyusun semua permutasi yang mungkin dari sekelompok karakter. Sebagai contoh, jika kita punyai 3 buah karakter A. B dan C, maka semua pennutasi yang mungkin dari ketiga karakter ini adalah :

ABC A C B B A C

B C A

CAB C B A

Secara umum, banyaknya permutasi dari N buah karakter adalah N faktorial. Dalam contoh

ill atas N = 3, sehingga banyaknya pennutasi adalah 3! = 6.

Proses penyusunan pennutasinya bisa dijelaskan sebagai berikut :

eetak e1emen ke 1. dan eetak permutasi elemen ke 2 sampai ke N (pennutasi dengan N-I elemen),

cetak elemen ke 2. dan eetak permutasi elemen ke I. elemen ke 3 sampai ke N (permutasi dengan N-l elemen),

eetak elemen ke 3. dan eetak pennutasi elemen ke I, elemen ke 2, elemen ke 4 sampai ke N (permutasi dengan N-l elemen),

dan seterusnya. sampai langkah terakhir adalah cetak elemen ke N, dan cetak perrnutasi elemen ke 1 sampai elemen ke (N-i) (pennutasi dengan N-l elemen).

Proses di atas diulang terns sampai dicctak pennutasi dengan 1 elemen.

27

Sebagai contoh, untuk N = 3, maka caranya adalah :

cetak 'A', dan cetak pennutasi (,B','C'); cetak 'B', dan cetak pennutasi ('A','C'); cetak 'C, dan cetak pennutasi CA','B');

Dari contoh di atas bisa dilihat bahwa banyaknya elemen yang dipennutasikan m lama makin sedildt sampai sarna dengan I. Kondisi inilah yang kita pakai sebagai ba proses. Program selengkapnya tersaji di bawah ini.

{ ********************************************************

'" Menyusun pennutasi sekelompok karakter dengan cara rekursif * .********************************************************** }

program SUSUN_PERMUT ASI;

uses crt;

const Max = 5;

type Larik = arrayl l..Max] of char,

var A : Larik.;

C_Pennutasi. C_Elemen, I

Lagi

{ *** larik yang akan dipermutasikan *** } { *** jumlah pennutasi selurunya *** }

{ *** banyaknya karakter *** }

{ *** perubah kendali *** }

{ *** perubah kendali *** }

: integer, : char.

{ ******************************************

* Prosedur penyustmatl pennutasi secara rekursif * ******************************************** }

procedure PERMUTASI (var B : integer,

A : Larik; K,N : integer);

var I : integer, Temp: char,

begin

if K = N then

begin

B := succ(B);

write('Pennutasi lee ',B:2,' : '); for I := 1 to N do

28

write(A[I]:3): writeln;

end else

for I := K to N do

begin

Temp := A[I]:

A(I] := A[K]:

A[K] := Temp:

PERMUT ASI (B.A,K+ t,N)

end

end: { *** prosedur PERMUf ASI *** }

begin { *** program utama *** }

clrscr;

repeat

write('Banyaknya karakter yang akan dipennutasikan: '); repeat

gotoxy(47,l);write(' '); gotoxy(47,l);readIn(C_Elemen)

until C _Elemen <= Max:

for I := 1 to C_Elemen do

A[I] := chr(I+64); clrscr;

writeln('MENYUSUN PERMUTASI UNTUK ',C_Elemen:2,' KARAKTER');

writelnC' ----------------------------------------------------------------- '): writeln; C_Pennutasi :=0;

PERMUT ASI (C_Pennutasi,A,l,C_Elemen); writeln;writeln( 'Banyalrnya permutasi: '.C _Pennutasi:3) writeln;write(' Akan coba lagi? (Y/f): '); readln(Lagi)

until not (Lagi in ['Y', 'y']

end. { *** program utama *** }

Program 2.4. Menyusun permutasi karakter.

29

Contob basil :

Banyaknya karakter yang akan dipermutasikan: 3

MENYUSUN PERMUTASI UNTUK 3 KARAKTER

Pennutasi ke 1 : A B C
Pennutasi ke 2 : A C C
Permutasi ke 3 : B A C
Pennutasi ke 4 : B C A
Permutasi ke 5 : C A B
Permutasi ke 6 : C B A
Banyaknya pennutasi: 6
2.4. MENARA HANOI Contoh paling umum dari rekursi adalah pennainan Menara Hanoi, yang berdas legenda, pertama kali dimainkan secara manual oleh seorang pendeta Budha di Hanoi, sehingg pennainan ini disebut Menara Hanoi. Dalam pennainan ini, akan dipindahkan sejumlah piringan yang tidak sama besarnya dari satu tonggak ke tonggak lain, dan diperbolehkan melewati tonggak bantuan Aturan pennainannya adalah sebagai berikut Sernua piringan pada tonggak A akan dipindah pada tonggak C dengan ketentuan bahwa pemindahan piringan dilakukan satu per satu dan piringan yang lebih besar tidak boleh diletakkan di atas piringan

'yang lebih kecil. Untuk jelasnya lihat Gambar 2.3. di bawah ini. I

Menurut legenda tersebut dikatakan bahwa jika anda selesai mernindahkan seluruh 64 I piringan, pada saat itu juga dunia kiamat. Ini menurut legenda, yang mungkin juga benar. Bayangkan jika untuk setiap pemindahan memerlukan waktu 1 (satu) detik. Anda bisa menghitung sendiri berapa detik yang diperlukan untuk memindahkan seluruh 64 piringan dari tonggak A ke tonggak C. Secara umum untuk menyelesaikan N buah piringan diperlukan pemindahan sebanyak 2N - 1 kali.

Tonggak asaJ (A)

Tonggak bantu (B)

Tonggak tujuan (C)

Gambar 23. lIustrasi permainan Menara Hanoi

30

Secara sedernana, pemindahan seluruh piringan secara rekursif dapat dilaksanakan dengan

1. pindahkan (N -1) piringan yang paling atas dart tonggak asal (A) ke tonggak bantu (B).

2. pindahkan piringan ke N (piringan terakhir) dari tonggak asal (A) ke tonggak tujuan (C).

3. pindahkan (N - 1) piringan dari tonggak. bantu (B) ke tonggak tujuan (C).

Tetapi, tentu saja, piringan sebanyak. (N - 1) buah tidak boleh dipindah bersama-sama, tetapi harus satu per saw. Dengan eara yang sarna seperti di atas, maka bisa dipindahkan ke (N - 1) buah piringan, satu piringan setiap saat, dari tonggak asal (A) ke tonggak bantu (B).

Untuk mempennudah penyelesaian persoalan kita conba membuat satu notasi bam, misalnya:

MEN ARA(N , Asal.Bantu,Tujuan)

Notasi di atas bisa dibaea: "pindahkan N buah piringan dari tonggak Asal ke tonggak Tujuan menggunakan tonggak Bantu.".

Jika N = 1. maka notasi di atas bisa ditulis sebagai :

MENARA(l,Asal,Bantu,Tujuan)

yang secara langsung bisa kita lak.sanakan dengan memindah piringan dari tempat Asal ke tempat Tujuan. Untuk N > 1. maka penyelesaiannya bisa kita pecah menjadi 3 penyelesaian seperti di atas, yaitu :

MENARA(N-l, Asal.Tujuan.Bantu); MENARA(N,Asal,Bantu.Tujuan); atau Asal -> Tujuan MENARA(N-l.Bantu,Asal,Tujuan);

MENARA(l,A,C.B) A -> B

MENARA(2.A,B,C.) l-.:, A -> C A -> C

~~ARA(1,B,A,c) B -> C

MENARA(3,A.C,B) A ->B A -> B

MENARA (I,C.B,A) C -> A

NARA(2.C,A,B)t--+C -> B C -> B

MENARA(l,A,C,B) A -> B

MENARA(4,A,B,C)t---~A -> C ~ " A -> C

MENARA(l.B,A,C) B -> A

MENARA(2,B,C,A)t--+B -> A B -> A

MENARA(1.C.B,A) C -> A

MENARA(3.B.A,C) B -> C B -> C

MENARA(l,A.C.B) A -> B

MENARA(2,A,B,C)t--+ A -> C . . . . .. A -> C MENARA(l.B,A,C) ... B -> C

Gambar 2.4. Pelacakan Menara Hanoi untuk 4 piringan.

31

Gambar 2.4. di atas menunjukkan pe1acakan dari penyelesaian Menara Hanoi denan buah piringan, yaitu :

MENARA(4.A.B,C)

yang telah kita hitung perlu 15 kali perpindahan, yaitu :

A-> B C-> B C-> A

A->C A-> B B-> C

B -> C A->C A-> B

A->B B-> C A-> C

C->A B -> A B-> C

Di bawah ini disajikan program untuk penyelesaian Menara Hanoi, dengan dibatas sampai 10 buah piringan.

{ ************************************************ * Penyelesaian persoalan Menara Hanoi dengan rekursi * * Banyaknya piringan dibatasi sampai 10 buah *

************************************************* }

program MENARA_HANOI;

uses crt;

const Max. = 10;

{ *** jumlah maksimum piringan *** }

var Gerakan, Piringan : integer.

{ *** banyaknya pemindahan yang diperlukan *** } { *** banyaknya piringan yang dicoba *** }

********************************

* Prosedur untuk memindah piringan * ********************************* }

procedure HANOI(var C_Gerak : integer;

Cacah : integer; A, B. C : char);

begin

if Cacah > 0 then

begin

HANOI(C_Gerak.Cacah-l.A.C,B); C_Gerak := succ(C_Gerak); writet'Langkah ke '.C_Gerak:3);

write(': pindah piring nomor '.Cacah:2); write(, dari tonggak ',A,' ke tonggak ',C); write1n(, (' ,A,' -> . ,C,')'):

32

HANOI(C_Gerak.Cacah-l,B,A,C)

end

end; { *** prosedur HANOI *** }

begin { *** program utama *** }

clrscr;

Gerakan := 0;

writeln(,PENYELESAIAN MENARA HANOI')

writeln('Piring terkecil diberi nomor I, berikutnya 2 dan seterusnya)');

writeln(' ---- ------------------------------------------------------------------- ' );

writeln; gotoxy( 1,5);

write('Banyaknya piringan (max' ,Max:2,'): '); writeln;

repeat

gotoxy(30,5);write(' '); gotoxy(30,5);readln(Piringan)

until Piringan <= Max; HANOI(Gernkan,Piringan,' A', 'B', 'C'); writeln;

write('Piringan sebanyak. • ,Piringan:2,' buah, memerlukan '): writeln( Gerakan:2,' kali pemindahan ')

end. { *** program utama *** }

Program 25. Menara Hanoi.

Contoh hasil :

PENYELESAIAN MENARA HANOI

(Piring terkecil diberi oomor 1, berikutnya 2 dan seterusnya)

Banyaknya piringan (max 10): 4

Langkah ke 1: pindah pi ring nomor 1 dari tonggak. A ke tonggak. B (A -c- B) Langkah ke ·2: pindah piring nomor 2 dari tonggak A ke tonggak. C (A ->C) Langkah ke 3: pindah piring nomor 1 dari tonggak B Ice tonggak C (B -> C) Langkah ke 4: pindah piring nomor 3 dari tonggak A ke tonggak. B (A -c- B) Langkah ke 5: pindah piring nomor 1 dari tonggak. C ke tonggak A (C -> A) Langkah ke 6: pindah piring oomor 2 dari tonggak C ke tonggak B (C -> B) Langkah ke 7: pindah piring nomor 1 dari tonggak A ke tonggak B (A -c- B) Langkah ke 8: pindah piring nomor 4 dari tonggak A ke tonggak C (A -c- C)

33

Langkah ke 9: pindall piring nomor 1 dari tonggak B ke tonggak C (B -> C) Langkah ke 10: pindah piling nomor 2 dari tonggak B ke tonggak A (B -> A) Langkah ke 11: pindah piling nomor 1 dari tonggak C ke tonggak A (C -> A) Langkah ke 12: pindah piling nomor 3 dari tonggak B ke tonggak C (B -> C) Langkah ke 13: pindah piling nomor 1 dari tonggak A ke tonggak B (A -> B) Langkah ke 14: pindah piling nomor 2 dari tonggak A ke tonggak C (A -> C) Langkah ke 15: pindah piring nomor 1 dari tonggak B ke tonggak C (B -> C)

Piringan sebanyak 4 buah, memerlukan 15 kali pemindahan.

Demikianlah pembahasan tentang proses rekursif dengan beberapa contoh programnya :

34

yang seeara notasi pemrograman bisa ditulis sebagai :

FAKTORIAL(O) ;;;; 1

FAKTORIAL(N) = N * FAKTORIAL(N - 1)

1) 2)

Persamaan 2) di atas merupakan eontoh hubungan rekurens (recurrence relation), yang berarti bahwa nilai suatu fungsi dengan argwnen tertentu bisa dihitung dari fungsi yang sam dengan argumen yang Iebih kecil Persamaan 1) yang tidak bersifat rekursif, disebut nilai awal. Setiap fungsi rekursi paling sedikit mempunyai 1 (satu) nilai awa1; jika tidak, fungsi tersebut tidak bisa dihitung secara eksplisit, I

Bilangan Fibonacci bisa didefmisikan berdasar deret integer tak terhingga sebagai berikut :

1 1 2 3 5 8 12 13 21 34 55 89 ...

Dari deret di atas bisa dilihat bahwa bilangan ke N (N) 2) dalam deret bisa dicari dari 2 (dua) bilangan sebelumnya yang terdekat dengan bilangan ke Nm yaitu bilangan ke (N-I) dan bilangan ke (N-2). Sehingga jika ABO(N) menunjukkan bilangan Fibonacci suku ke N, maka FlBO(N) bisa dihitung berdasar hubungan rekurens :

FIBO(N) = FlBO(N - 1) + FIBO(N - 2)

Karena FlBO(N) ditentukan oleh dua nilai yang berbeda dengan argumen yang Iebih kecil, maka untuk meneari bilangan fibonacci diperlukan 2 (dua) nilai awal, yaitu :

FIBO(1) = 1 dan

ABO(2) - 2

2.1. PROSES REKURSIF

Untuk memahami proses rekursif yang teIjadi dalam sebuah fungsi rekursif, perbatikan contoh sederhana di bawah Uti. Contoh di bawah ini menyajikan satu fungsi untuk menghitung harga faktoral suatu integer seperti yang telah dijelaskan di alas.

Dari definisi di atas, bisa dibuat fungsi F AKT sebagai berikut :

{ *********************************************************

* Fungsi untuk menghitung bilangan faktorial dengan eara rekursif * ********************************************************* } function F AKT(N : integer) : integer;

begin

if N ;;;; 0 then FAKT :~ 1 else

FAKT := N * FAKT(N - 1)

end;

Program 2.1. Fakiorial dengan cara rekursif

24

Dari fungsi di atas bisa dilihat bahwa FAKT(N) bisa dihitung dari FAKT (N-I), dimana FAKT(N-l) bisa dihitung dari FAKT(N-2) dan seterusnya. Dengan demikian, fungsi eli atas untuk N = 6 bisa kita lacak cara kerjanya, yaitu seperti terlihat pada Gambar 2.1.

Perhatikan bahwa untuk menghitung F AKT(N), maka fungsi hams memanggil nilai F AKT(N-I) yang telah diperoleh. Demikian juga untuk menghitung nilai FAKT(N -I), fungsi harus memanggil nilai F AKT(N - 2) dan seterusnya. Notasi F AKT(N -1), yang digunakan untuk memanggil nilai fungsi sebelumnya, sering disebut dengan pemanggil rekursif atau recursion call. Dalam ilustrasi di atas, pemanggil rekursi ditunjukkan dengan tanda anak panah. Sarna halnya dengan prosedur atau fungsi yang lain, maka dalam rekursi pasti ada pemanggil rekursi,

.Dengan eara yang sama, bisa dilihat fungsi FlBO untuk menghitung bilangan Fibonacci pada suatu suku ke N, yaitu seperti yang tersaji dalam Program 2.2. Pelacakan fungsi FIBO di atas untuk N = 6 adalah seperti pada Gambar 2.2.

FAKT(6) = 6 * FAKT(5) t

I FAKT(5) = 5 * FAKT(4) l'

I FAKT(4) = 4 * FAKT(3) .1'

I FAKT(3) = 3 * FAKT(2)

t

I F AKT(2) = 2 * FAKT(1) t

I FAKT(1) = 1 * FAKT(O)

nil.Tal

31 aw

Gombar 2.1. llustrasi fungsi F AKT dengan proses rekursif.

FIBO(6) = FIBO(5) + FlBO(4)

,....----Jt t

I

FIB0(5) = FIBO(4) + FIBO(3)

,....----J1' l'

I I

FIBO(4) = FIBO(3) + ABO(2)

I' n;11 awal

FIBO(3) = FlBO(2) + FIBO(l)

nilai i al . taT al

ai aw m 1 aw

Gambar 2.2. llustrasi fungsi FIBO dengan proses rekursif.

25

{ ********************************************************** * Prosedur untuk menghitung bilangan Fibonacci dengan earn rekursif * ************************************************************

function FIBO(N : integer) : integer,

begin

if (N = 1) or (N = 2) then FIBO := 1

else

FIBO(N) := FIBO(N - 1) + FIBO(N - 2)

end;

Program 2.2. Deret Fibonacci dengan cara rekursif.

2.2. TEKNIK REKURSIF DAN TEKNIK ITERATIF

Dalam beberapa hal, rekursi kurang efisien dibanding proses iterasi. Bandingkan fungsi FIBO di atas dengan fungsi di bawah ini yang juga digunakan untuk menghitung bilangan Fibonacci, tetapi dilaksanakan dengan eara iterasi.

{ ********************************************************

* Fungsi untuk menghitung bilangan Fibonacci dengan cara iteasi * ********************************************************* }

function FIBO_ITER(N : integer) : integer, var F, akhir, Bantu, 1 ; .Integer

begin

1 := 1; F := 1; akhir := 0; if N = 0 then F := 0; while I <> N do

begin

Bantu := F; I :;;:: I + 1; F := F + Akhir:

Akhir := Bantu end;

FIBO_ITER := F

end;

Program 23. Deret Fibonacci dengan cara iterasi.

26

Dalam contoh pertama (fungsi FIBO yang menggunakan proses rekursif), suatu bilangan pada suku ke N akan diperoleh melalui hubungan rekurens. Sebaliknya, cara rekursif seperti di atas adalah kurang nyata, karena ada 2 (dua) pemanggil rekursif dillruti yang lain Meskipun demikian, eara rekursif di alas menjadi terla1u jelek, karena kedalaman pemanggil rekursif sangat diperlukan dan juga karena pengulangan penghitungan dart suatu hasil yang sebenarnya telah dihitung. Sebagai contoh, AB0(6) memerlukan FIB 0(5), yang selanjutnya memerlukan FIBO(4), FIBO(3) dan seterusnya

Dalam beberapa situasi, pemecahan secara rekursif dan secara iteratif mempunyai keuntungan dan kekurangan yang bisa saling dipeIbandingkan. Adalah cukup sulit untuk menentukan mana yang paling sederhana, paling jelas, paling efisien dan paling mudah dibanding yang lain. Bisa ditambahkan, pemilihan cara iteratif maupun eara rekursif boleh dikatakan merupakan kesenangan seorang programer sesuai dengan kesanggupan dan eita rasanya.

2.3. MENYUSUN PERMUTASI

Contoh lain dart proses rekursif yang akan disajikan adalah untuk menyusun semua permutasi yang mungkin dari sekelompok karakter. Sebagai contoh, jika kita punyai 3 buah karakter A. B dan C, maka semua pennutasi yang mungkin dari ketiga karakter ini adalah :

ABC A C B B A C

B C A

CAB C B A

Secara umum, banyaknya permutasi dari N buah karakter adalah N faktorial. Dalam contoh

ill atas N = 3, sehingga banyaknya pennutasi adalah 3! = 6.

Proses penyusunan pennutasinya bisa dijelaskan sebagai berikut :

eetak e1emen ke 1. dan eetak permutasi elemen ke 2 sampai ke N (pennutasi dengan N-I elemen),

cetak elemen ke 2. dan eetak permutasi elemen ke I. elemen ke 3 sampai ke N (permutasi dengan N-l elemen),

eetak elemen ke 3. dan eetak pennutasi elemen ke I, elemen ke 2, elemen ke 4 sampai ke N (permutasi dengan N-l elemen),

dan seterusnya. sampai langkah terakhir adalah cetak elemen ke N, dan cetak perrnutasi elemen ke 1 sampai elemen ke (N-i) (pennutasi dengan N-l elemen).

Proses di atas diulang terns sampai dicctak pennutasi dengan 1 elemen.

27

Sebagai contoh, untuk N = 3, maka caranya adalah :

cetak 'A', dan cetak pennutasi (,B','C'); cetak 'B', dan cetak pennutasi ('A','C'); cetak 'C, dan cetak pennutasi CA','B');

Dari contoh di atas bisa dilihat bahwa banyaknya elemen yang dipennutasikan m lama makin sedildt sampai sarna dengan I. Kondisi inilah yang kita pakai sebagai ba proses. Program selengkapnya tersaji di bawah ini.

{ ********************************************************

'" Menyusun pennutasi sekelompok karakter dengan cara rekursif * .********************************************************** }

program SUSUN_PERMUT ASI;

uses crt;

const Max = 5;

type Larik = arrayl l..Max] of char,

var A : Larik.;

C_Pennutasi. C_Elemen, I

Lagi

{ *** larik yang akan dipermutasikan *** } { *** jumlah pennutasi selurunya *** }

{ *** banyaknya karakter *** }

{ *** perubah kendali *** }

{ *** perubah kendali *** }

: integer, : char.

{ ******************************************

* Prosedur penyustmatl pennutasi secara rekursif * ******************************************** }

procedure PERMUTASI (var B : integer,

A : Larik; K,N : integer);

var I : integer, Temp: char,

begin

if K = N then

begin

B := succ(B);

write('Pennutasi lee ',B:2,' : '); for I := 1 to N do

28

write(A[I]:3): writeln;

end else

for I := K to N do

begin

Temp := A[I]:

A(I] := A[K]:

A[K] := Temp:

PERMUT ASI (B.A,K+ t,N)

end

end: { *** prosedur PERMUf ASI *** }

begin { *** program utama *** }

clrscr;

repeat

write('Banyaknya karakter yang akan dipennutasikan: '); repeat

gotoxy(47,l);write(' '); gotoxy(47,l);readIn(C_Elemen)

until C _Elemen <= Max:

for I := 1 to C_Elemen do

A[I] := chr(I+64); clrscr;

writeln('MENYUSUN PERMUTASI UNTUK ',C_Elemen:2,' KARAKTER');

writelnC' ----------------------------------------------------------------- '): writeln; C_Pennutasi :=0;

PERMUT ASI (C_Pennutasi,A,l,C_Elemen); writeln;writeln( 'Banyalrnya permutasi: '.C _Pennutasi:3) writeln;write(' Akan coba lagi? (Y/f): '); readln(Lagi)

until not (Lagi in ['Y', 'y']

end. { *** program utama *** }

Program 2.4. Menyusun permutasi karakter.

29

Contob basil :

Banyaknya karakter yang akan dipermutasikan: 3

MENYUSUN PERMUTASI UNTUK 3 KARAKTER

Pennutasi ke 1 : A B C
Pennutasi ke 2 : A C C
Permutasi ke 3 : B A C
Pennutasi ke 4 : B C A
Permutasi ke 5 : C A B
Permutasi ke 6 : C B A
Banyaknya pennutasi: 6
2.4. MENARA HANOI Contoh paling umum dari rekursi adalah pennainan Menara Hanoi, yang berdas legenda, pertama kali dimainkan secara manual oleh seorang pendeta Budha di Hanoi, sehingg pennainan ini disebut Menara Hanoi. Dalam pennainan ini, akan dipindahkan sejumlah piringan yang tidak sama besarnya dari satu tonggak ke tonggak lain, dan diperbolehkan melewati tonggak bantuan Aturan pennainannya adalah sebagai berikut Sernua piringan pada tonggak A akan dipindah pada tonggak C dengan ketentuan bahwa pemindahan piringan dilakukan satu per satu dan piringan yang lebih besar tidak boleh diletakkan di atas piringan

'yang lebih kecil. Untuk jelasnya lihat Gambar 2.3. di bawah ini. I

Menurut legenda tersebut dikatakan bahwa jika anda selesai mernindahkan seluruh 64 I piringan, pada saat itu juga dunia kiamat. Ini menurut legenda, yang mungkin juga benar. Bayangkan jika untuk setiap pemindahan memerlukan waktu 1 (satu) detik. Anda bisa menghitung sendiri berapa detik yang diperlukan untuk memindahkan seluruh 64 piringan dari tonggak A ke tonggak C. Secara umum untuk menyelesaikan N buah piringan diperlukan pemindahan sebanyak 2N - 1 kali.

Tonggak asaJ (A)

Tonggak bantu (B)

Tonggak tujuan (C)

Gambar 23. lIustrasi permainan Menara Hanoi

30

Secara sedernana, pemindahan seluruh piringan secara rekursif dapat dilaksanakan dengan

1. pindahkan (N -1) piringan yang paling atas dart tonggak asal (A) ke tonggak bantu (B).

2. pindahkan piringan ke N (piringan terakhir) dari tonggak asal (A) ke tonggak tujuan (C).

3. pindahkan (N - 1) piringan dari tonggak. bantu (B) ke tonggak tujuan (C).

Tetapi, tentu saja, piringan sebanyak. (N - 1) buah tidak boleh dipindah bersama-sama, tetapi harus satu per saw. Dengan eara yang sarna seperti di atas, maka bisa dipindahkan ke (N - 1) buah piringan, satu piringan setiap saat, dari tonggak asal (A) ke tonggak bantu (B).

Untuk mempennudah penyelesaian persoalan kita conba membuat satu notasi bam, misalnya:

MEN ARA(N , Asal.Bantu,Tujuan)

Notasi di atas bisa dibaea: "pindahkan N buah piringan dari tonggak Asal ke tonggak Tujuan menggunakan tonggak Bantu.".

Jika N = 1. maka notasi di atas bisa ditulis sebagai :

MENARA(l,Asal,Bantu,Tujuan)

yang secara langsung bisa kita lak.sanakan dengan memindah piringan dari tempat Asal ke tempat Tujuan. Untuk N > 1. maka penyelesaiannya bisa kita pecah menjadi 3 penyelesaian seperti di atas, yaitu :

MENARA(N-l, Asal.Tujuan.Bantu); MENARA(N,Asal,Bantu.Tujuan); atau Asal -> Tujuan MENARA(N-l.Bantu,Asal,Tujuan);

MENARA(l,A,C.B) A -> B

MENARA(2.A,B,C.) l-.:, A -> C A -> C

~~ARA(1,B,A,c) B -> C

MENARA(3,A.C,B) A ->B A -> B

MENARA (I,C.B,A) C -> A

NARA(2.C,A,B)t--+C -> B C -> B

MENARA(l,A,C,B) A -> B

MENARA(4,A,B,C)t---~A -> C ~ " A -> C

MENARA(l.B,A,C) B -> A

MENARA(2,B,C,A)t--+B -> A B -> A

MENARA(1.C.B,A) C -> A

MENARA(3.B.A,C) B -> C B -> C

MENARA(l,A.C.B) A -> B

MENARA(2,A,B,C)t--+ A -> C . . . . .. A -> C MENARA(l.B,A,C) ... B -> C

Gambar 2.4. Pelacakan Menara Hanoi untuk 4 piringan.

31

Gambar 2.4. di atas menunjukkan pe1acakan dari penyelesaian Menara Hanoi denan buah piringan, yaitu :

MENARA(4.A.B,C)

yang telah kita hitung perlu 15 kali perpindahan, yaitu :

A-> B C-> B C-> A

A->C A-> B B-> C

B -> C A->C A-> B

A->B B-> C A-> C

C->A B -> A B-> C

Di bawah ini disajikan program untuk penyelesaian Menara Hanoi, dengan dibatas sampai 10 buah piringan.

{ ************************************************ * Penyelesaian persoalan Menara Hanoi dengan rekursi * * Banyaknya piringan dibatasi sampai 10 buah *

************************************************* }

program MENARA_HANOI;

uses crt;

const Max. = 10;

{ *** jumlah maksimum piringan *** }

var Gerakan, Piringan : integer.

{ *** banyaknya pemindahan yang diperlukan *** } { *** banyaknya piringan yang dicoba *** }

********************************

* Prosedur untuk memindah piringan * ********************************* }

procedure HANOI(var C_Gerak : integer;

Cacah : integer; A, B. C : char);

begin

if Cacah > 0 then

begin

HANOI(C_Gerak.Cacah-l.A.C,B); C_Gerak := succ(C_Gerak); writet'Langkah ke '.C_Gerak:3);

write(': pindah piring nomor '.Cacah:2); write(, dari tonggak ',A,' ke tonggak ',C); write1n(, (' ,A,' -> . ,C,')'):

32

HANOI(C_Gerak.Cacah-l,B,A,C)

end

end; { *** prosedur HANOI *** }

begin { *** program utama *** }

clrscr;

Gerakan := 0;

writeln(,PENYELESAIAN MENARA HANOI')

writeln('Piring terkecil diberi nomor I, berikutnya 2 dan seterusnya)');

writeln(' ---- ------------------------------------------------------------------- ' );

writeln; gotoxy( 1,5);

write('Banyaknya piringan (max' ,Max:2,'): '); writeln;

repeat

gotoxy(30,5);write(' '); gotoxy(30,5);readln(Piringan)

until Piringan <= Max; HANOI(Gernkan,Piringan,' A', 'B', 'C'); writeln;

write('Piringan sebanyak. • ,Piringan:2,' buah, memerlukan '): writeln( Gerakan:2,' kali pemindahan ')

end. { *** program utama *** }

Program 25. Menara Hanoi.

Contoh hasil :

PENYELESAIAN MENARA HANOI

(Piring terkecil diberi oomor 1, berikutnya 2 dan seterusnya)

Banyaknya piringan (max 10): 4

Langkah ke 1: pindah pi ring nomor 1 dari tonggak. A ke tonggak. B (A -c- B) Langkah ke ·2: pindah piring nomor 2 dari tonggak A ke tonggak. C (A ->C) Langkah ke 3: pindah piring nomor 1 dari tonggak B Ice tonggak C (B -> C) Langkah ke 4: pindah piring nomor 3 dari tonggak A ke tonggak. B (A -c- B) Langkah ke 5: pindah piring nomor 1 dari tonggak. C ke tonggak A (C -> A) Langkah ke 6: pindah piring oomor 2 dari tonggak C ke tonggak B (C -> B) Langkah ke 7: pindah piring nomor 1 dari tonggak A ke tonggak B (A -c- B) Langkah ke 8: pindah piring nomor 4 dari tonggak A ke tonggak C (A -c- C)

33

Langkah ke 9: pindall piring nomor 1 dari tonggak B ke tonggak C (B -> C) Langkah ke 10: pindah piling nomor 2 dari tonggak B ke tonggak A (B -> A) Langkah ke 11: pindah piling nomor 1 dari tonggak C ke tonggak A (C -> A) Langkah ke 12: pindah piling nomor 3 dari tonggak B ke tonggak C (B -> C) Langkah ke 13: pindah piling nomor 1 dari tonggak A ke tonggak B (A -> B) Langkah ke 14: pindah piling nomor 2 dari tonggak A ke tonggak C (A -> C) Langkah ke 15: pindah piring nomor 1 dari tonggak B ke tonggak C (B -> C)

Piringan sebanyak 4 buah, memerlukan 15 kali pemindahan.

Demikianlah pembahasan tentang proses rekursif dengan beberapa contoh programnya :

34

LATIHAN 2

A. PILIHLAH SATU JAWABAN YANG PALING TEPAT ! 2. 1. Suatu proses yang bisa memanggil dirinya sendiri disebut

A. iteratif

B. rekursif

C. transitif

2. 2. Jika suatu fungsi dengan argumen tertentu bisa dihitung dari fungsi yang sarna dengan argumen yang lebih kecil, disebut

A. kombinatorik

B. relasi

C. hubungan rekurens

Perhatikan algoritrna berikut untuk menjawab soal 2.3, 2.4, 25 dan 2.10 ! PROCEDURE F(n : integer) : integer

IF n ::;; 1 THEN F = 1

ELSE

F = n * F(n-l) ENDIF

END_F

2.3. Jika input n = 6 maka outputnya adalah

A. 24

B. 120

C. 720

2.4. Untuk n = 8 terjadi pemanggilan ulang prosectur F sebanyak

A. 7

B. 256

C. 126

2.5. Apabila ctengan n input data maka pemanggilan ulang prosedur f adalah sebanyak

A. (n-I) kali

B. n! kali

C. 2(n2 _ 1) kali

35

2.6. Untuk menyelesaikan masalah menara Hanoi dengan banyaknya piringan ialah 6 maka diperlukan pemindahan sebanyak

A. 19 kali

B. 31 kali

C. 63 kali"

Untuk soal nomor 2.7, 2.8 dan 2.9 diberikan algoritma berikut. PROCEDURE A(n : integer) : integer

IFn:52thenA=1

ELSE

A(n) = A(n--l) + A(n--2) ENDIF

END_A

2.7. Dengan memasukkan input data sebesar 7 maka akan diperoleh outputnya sebesar

A. 55

B. 21

C. 12

2.8. Banyaknya pemanggilan u1ang prosedur A untuk. input data sarna dengan 6 adalah A 8 kali

B. 10kali

C. 13 kali

2.9. Bila diberikan nilai n sarna dengan 13 maka outputnya ialah A 89

B. 144

C. 178

2.10 Kompleksitas waktunya adalah A 0 (n--l)

B. 0 (n)

C. 0 (n2)

36

You might also like