Rekursif
Fungsi rekursif merupakan fungsi yang memanggil dirinya sendiri.
Terdapat dua komponen penting dalam fungsi rekursif, yaitu kondisi kapan
berhentinya fungsi dan pengurangan atau pembagian dataketika fungsi
memanggil dirinya sendiri. Optimasi fungsi rekursif dapat dilakukan
dengan menggunakan teknik tail call, meskipun teknik ini tidak selalu
diimplementasikan oleh semua bahasa pemrograman. Selain sebagai fungsi, konsep rekursif juga terkadang digunakan untuk struktur data seperti binary tree atau list. Salah satu konsep paling dasar dalam ilmu komputer dan pemrograman
adalah pengunaan fungsi sebagai abstraksi untuk kode-kode yang digunakan
berulang kali. Kedekatan ilmu komputer dengan matematika juga
menyebabkan konsep-konsep fungsi pada matematika seringkali dijumpai.
Salah satu konsep fungsi pada matematika yang ditemui pada ilmu komputer
adalah fungsi rekursif: sebuah fungsi yang memanggil dirinya sendiri.
Kode berikut memperlihatkan contoh fungsi rekursif, untuk menghitung hasil kali dari dua bilangan:
def kali(a, b):
return a if b == 1 else a + kali(a, b - 1)
Bagaimana cara kerja fungsi rekursif ini? Sederhananya, selama nilai
b
bukan 1
, fungsi akan terus memanggil perintah a + kali(a, b - 1)
, yang tiap tahapnya memanggil dirinya sendiri sambil mengurangi nilai b
. Mari kita coba panggil fungsi kali
dan uraikan langkah pemanggilannya:
kali(2, 4)
-> 2 + kali(2, 3)
-> 2 + (2 + kali(2, 2))
-> 2 + (2 + (2 + kali(2, 1)))
-> 2 + (2 + (2 + 2))
-> 2 + (2 + 4)
-> 2 + 6
-> 8
Perhatikan bahwa sebelum melakukan penambahan program melakukan
pemanggilan fungsi rekursif terlebih dahulu sampai fungsi rekursif
mengembalikan nilai pasti (2 ).
Setelah menghilangkan semua pemanggilan fungsi, penambahan baru
dilakukan, mulai dari nilai kembalian dari fungsi yang paling terakhir.
Mari kita lihat contoh fungsi rekursif lainnya, yang digunakan untuk
melakukan perhitungan faktorial:
def faktorial(n):
return n if n == 1 else n * faktorial(n - 1)
Fungsi
faktorial
memiliki cara kerja yang sama dengan fungsi kali
. Mari kita panggil dan lihat langkah pemanggilannya:
faktorial(5)
-> 5 * faktorial(4)
-> 5 * (4 * faktorial(3))
-> 5 * (4 * (3 * faktorial(2)))
-> 5 * (4 * (3 * (2 * faktorial(1))))
-> 5 * (4 * (3 * (2 * 1)))
-> 5 * (4 * (3 * 2))
-> 5 * (4 * 6)
-> 5 * 24
-> 120
Dengan melihat kemiripan cara kerja serta kode dari fungsi
faktorial
dan kali
, kita dapat melihat bagaimana fungsi rekursif memiliki dua ciri khas:- Fungsi rekursif selalu memiliki kondisi yang menyatakan kapan fungsi tersebut berhenti. Kondisi ini harus dapat dibuktikan akan tercapai, karena jika tidak tercapai maka kita tidak dapat membuktikan bahwa fungsi akan berhenti, yang berarti algoritma kita tidak benar.
- Fungsi rekursif selalu memanggil dirinya sendiri sambil mengurangi atau memecahkan data masukan setiap panggilannya. Hal ini penting diingat, karena tujuan utama dari rekursif ialah memecahkan masalah dengan mengurangi masalah tersebut menjadi masalah-masalah kecil.
Setiap fungsi rekursif yang ada harus memenuhi kedua persyaratan di
atas untuk memastikan fungsi rekursif dapat berhenti dan memberikan
hasil. Kebenaran dari nilai yang dihasilkan tentu saja memerlukan
pembuktian dengan cara tersendiri. Tetapi sebelum masuk ke analisa dan
pembuktian fungsi rekursif, mari kita lihat kegunaan dan contoh-contoh
fungsi rekursif lainnya lagi.
Prosedur dan fungsi Rekursif
Prosedur
dan fungsi merupakan sub program yang sangat bermanfaat dalam
pemrograman, terutama untuk program atau proyek yang besar. Manfaat
penggunaan sub program antara lain adalah :
Prosedur dan fungsi
merupakan sub program yang sangat bermanfaat dalam pemrograman, terutama
untuk program atau proyek yang besar. Manfaat penggunaan sub program
antara lain adalah :
1. meningkatkan readibility, yaitu mempermudah pembacaan program
2. meningkatkan modularity, yaitu memecah sesuatu yang besar menjadi
modul-modul atau bagian-bagian yang lebih kecil sesuai dengan fungsinya,
sehingga mempermudah pengecekan, testing dan lokalisasi kesalahan.
3. meningkatkan reusability, yaitu suatu sub program dapat dipakai
berulang kali dengan hanya memanggil sub program tersebut tanpa
menuliskan perintah-perintah yang semestinya diulang-ulang.
Sub Program Rekursif adalah sub program yang memanggil dirinya sendiri selama kondisi pemanggilan dipenuhi.
adalah Dengan melihat sifat sub program rekursif di atas maka sub program rekursif harus memiliki :
1. kondisi yang menyebabkan pemanggilan dirinya berhenti (disebut kondisi khusus atau special condition)
2. pemanggilan diri sub program (yaitu bila kondisi khusus tidak dipenuhi)
Secara umum bentuk dari sub program rekursif memiliki statemen kondisional :
if kondisi khusus tak dipenuhi
then panggil diri-sendiri dengan parameter yang sesuai
else lakukan instruksi yang akan dieksekusi bila kondisi khusus dipenuhi
Sub
program rekursif umumnya dipakai untuk permasalahan yang memiliki
langkah penyelesaian yang terpola atau langkah-langkah yang teratur.
Bila kita memiliki suatu permasalahan dan kita mengetahui algoritma
penyelesaiannya, kadang-kadang sub program rekursif menjadi pilihan kita
bila memang memungkinkan untuk dipergunakan. Secara algoritmis (dari
segi algoritma, yaitu bila kita mempertimbangkan penggunaan memori,
waktu eksekusi sub program) sub program rekursif sering bersifat tidak
efisien .
Dengan demikian sub program rekursif umumnya memiliki
efisiensi dalam penulisan perintah, tetapi kadang tidak efisien secara
algoritmis. Meskipun demikian banyak pula permasalahan-permasalahan yang
lebih sesuai diselesaikan dengan cara rekursif (misalnya dalam
pencarian / searching, yang akan dibahas pada pertemuan-pertemuan yang
akan datang).
Contoh sub program rekursif dalam bahasa Pascal.
1. Contoh sederhana
PROCEDURE TULIS_1(banyak : integer;kata : string);
begin
if banyak > 1 then TULIS_1(banyak-1,kata);
writeln(kata, banyak:5);
end;
OUTPUT (misal dipanggil dengan TULIS_1(5,"Cetakan ke "))
Cetakan ke 1
Cetakan ke 2
Cetakan ke 3
Cetakan ke 4
Cetakan ke 5
Bandingkan prosedur dan outputnya di atas dengan prosedur di bawah ini!
PROCEDURE TULIS_2(banyak : integer;kata : string);
begin
writeln(kata, banyak:5);
if banyak > 1 then TULIS_1(banyak-1,kata);
end;
OUTPUT (misal dipanggil dengan TULIS_2(5,"Cetakan ke "))
Cetakan ke 5
Cetakan ke 4
Cetakan ke 3
Cetakan ke 2
Cetakan ke 1
Mengapa hasilnya jauh berbeda?
2. Contoh terapan
Secara matematis, perkalian dua bilangan bulat positif a
dengan b (ditulis ab atau a x b) pada hakekatnya merupakan penjumlahan
dari a sebanyak b suku, yaitu a + a + a + …. + a sebanyak b suku.
Misalnya 2 x 3 dapat diartikan sebagai 2 + 2 + 2 = 6 , yaitu penjumlahan
2 sebanyak 3 suku Dengan mengingat bahwa suatu bilangan bila
dikalikan dengan angka 1 (satu) akan menghasilkan bilangan itu sendiri,
maka permasalahan perkalian dengan menyatakannya dalam bentuk
penjumlahan di atas dapat diselesaikan dengan komputer secara mudah.
Dengan non rekursif
1. Dengan prosedur
Procedure KALI_BIASA_P(a,b : integer; var hasil : longint);
var i : integer;
begin
hasil := 0;
for i:= 1 to b do hasil := hasil + a;
end;
2. Dengan fungsi
Function KALI_BIASA_F(a,b:integer):longint;
var hasil : longint; i: integer;
begin
hasil := 0;
for i:= 1 to b do hasil := hasil + a;
KALI_BIASA_F := hasil;
end;
Dengan Rekursif
1. Dengan Prosedur
Procedure KALI_REK_P(a,b:integer;var hasil:longint)
begin
if b>1 then KALI_REK_P(a,b-1,hasil);
hasil:= hasil+a;
end;
2. Dengan Fungsi
Function KALI_REK_F(a,b:integer):longint;
begin
if b>1 then
KALI_REK_F := KALI_REK_F(a,b-1)+a
else
KALI_REK_F := a;
end;
TUGAS :
1. Ubahlah prosedur perkalian di atas ( contoh 2.i dan 2.ii )
sehingga outputnya bukanlah hasil perkalian tetapi hasil pemangkatan.
Misal parameter a:= 3 dan b:= 2, hasil yang diberikan bukanlah 6 (yaitu
3x2) tetapi outputnya adalah 9 (yaitu 3 pangkat 2)
2. Buatlah program secara lengkap dimana program tersebut memanggil atau mempergunakan fungsi/prosedur di atas!
RECORD (REKAMAN)
Record adalah tipe terstruktur yang terdiri atas sejumlah elemen yang tipenya tidak harus sama.
Elemen
di dalam suatu record disebut dengan istilah field (medan). Sebelumnya
sudah dibicarakan struktur data yang juga memiliki sejumlah elemen yaitu
array. Perbedaan utama dari keduanya adalah bahwa elemen dalam suatu
array semuanya memiliki tipe yang sama sedang elemen-elemen di dalam
rekaman tidak harus bertipe sama. Contoh :
type LARIK = array [1..100] of real;
var a : larik;
Dari
deklarasi di atas berarti kita mendefinisikan suatu tipe data baru
bernama LARIK yang merupakan array berisi data real dengan elemen
maksimum yang dapat ditampung sebanyak 100 yang ditandai sebagai elemen
ke-1, ke-2, ke-3 dan seterusnya. Salah satu variabel yang memiliki tipe
LARIK adalah variabel A. Dengan demikian variabel A dapat menampung data
maksimum sebanyak 100 dan data yang disimpan harus bertipe real.. Untuk
memahami tipe data record perhatikan contoh tabel data mahasiswa di
bawah ini.
NIM NAMA USIA JML_SAUDARA
5234 K Mustofa 26 2
5233 AS Anandya S 25 1
5127 Dina A 23 3
4006 Yadi 20 5
Bila kita perhatikan tabel di atas, kita peroleh gambaran:
1. dalam 1 kolom, tipe data yang diisikan pasti sama (misal NIM
dideklarasikan sebagai data numeric (integer misalnya) maka semua NIM
harus berupa data angka)
2. suatu obyek dapat dikenali
secara tunggal menggunakan gabungan nilai data kolom-kolom dalam setiap
barisnya. (misal : gabungan nilai NIM ‘5234’, NAMA ‘K. Mustofa’, USIA
‘26’ dan JML_SAUDARA ‘2’ mengacu pada suatu obyek yang tertentu yaitu
seseorang)
Di dalam konsep database, kolom dalam suatu tabel
seperti di atas disebut sebagai atribut atau field. Sedang gabungan
field-field dalam suatu baris disebut tuple atau record. Dengan
deskripsi di atas, dapat dikatakan bahwa seorang mahasiswa dapat
dinyatakan sebagai suatu record yang memiliki 4 data (elemen) yaitu
field NIM, field NAMA, field USIA dan field JML_SAUDARA.
Bagaimanakan representasi record dalam PASCAL?
Record dalam bahasa pascal dapat dideklarasikan dengan cara (bentuk umum) sebagai berikut:
TYPE nama_pengenal_record = RECORD
nama_field1: type_field1;
nama_field2: type_field2;
nama_field3: type_field3;
:
:
nama_fieldn: type_fieldn;
END;
Dengan mengambil contoh data mahasiswa di atas, kita dapat memiliki deklarasi sebagai berikut:
TYPE mhs = RECORD
nim : integer;
nama: string[30];
usia: byte;
jml_saudara: 0..15;
END;
Bagaimana Menggunakan Tipe Data Record dan Mengakses Field-Field di dalamnya?
Kalau
kita sudah memiliki deklarasi record seperti di atas, maka untuk
menggunakannya di dalam program tentunya kita tinggal memesan
variabel-variabel yang kita perlukan dengan perintah VAR. Perhatikan
contoh berikut:
var satu : mhs;
banyak : array[1..20] of mhs;
Deklarasi
/ pemesanan variabel di atas berarti program memerlukan alokasi memori
yang akan dipergunakan untuk menyimpan data bertipe mhs. Variabel "satu"
dapat dipergunakan untuk menyimpan data satu mahasiswa, sedang variabel
"banyak" dapat dipergunakan untuk menyimpan maksimum 20 data mahasiswa.
Untuk mengakses data bertipe record kita tidak dapa melakukannya dengan
satu langkah seperti halnya ketika kita mengakses suatu variabel
sederhana. Kalau kita memiliki variabel p bertipe sederhana (integer,
byte, word, char, real) maka untuk memberikan nilai kira dapat
menggunakan operator assignment (:=) atau untuk membaca masukan dari
user kita dapat melakukannya dengan perintah readln(p), tetapi dengan
data/variabel bertipe record kita tidak dapat melakukannya sesederhana
itu. Untuk mengakses fiel-field pada suatu variabel bertipe record dapat
dilakukan dengan dua cara :
1. dengan menggunakan operator/notasi titik
Syntax secara umum :
nama_variabel_record . nama_field
Contoh berikut adalah sah:
1. readln(satu.nim); readln(satu.nama);
2. satu.nama := ‘AMIKOM’;
3. banyak[1]. nim := 5558;
4. banyak[6].nama := ‘YOGYAKARTA’;
2. dengan menggunakan statemen pembatas with … do
Syntax secara umum :
with nama_variabel do
begin
lakukan operasi terhadap field-field
-----
-----
end;
Contoh berikut adalah valid :
1. with satu do readln(nama)
2. with satu do begin
readln(nama);{sama artinya dengan readln (satu.nama)}
readln(nim);
readln(usia);
jml_saudara := 5; {sama artinya dengan satu.jml_saudara := 5}
nama:= ‘AKU’
end;
3. with banyak[5] do begin
readln(usia);
readln(nama);
end;
Contoh program :
Program contoh_rekaman;
uses crt;
type mhs = record
nim: string[8];
nama: string[30];
usia: byte;
jml_saudara: 0..20;
end;
var siswa : array[1..20] of mhs;
i, n : integer;
begin
clrscr;
write(‘Banyak data yang akan dimasukkan : ‘); readln(n);
{langkah pemasukan data}
for i:= 1 to n do
begin
clrscr;
writeln(‘Data ke : ‘,i);
with siswa[i] do
begin write(‘ NIM : ‘);readln(nim);
write(‘NAMA : ‘);readln(nama);
write(‘USIA : ‘);readln(usia);
write(‘SAUDARA : ‘);readln(jml_saudara);
end;
end;
{penampilan data}
clrscr;
writeln(‘DATA YANG ANDA MASUKKAN ‘);
writeln;
for i:= 1 to n do
begin
write(siswa[i].nim:11);
write(siswa[i].nama:23);
write(siswa[i].usia:5);
write(siswa[i].jml_saudara:5);
writeln;
end;
readln;
end.
Sekian Pembahasan tentang rekursif dan prosedur beserta fungsinya. Terima Kasih
Sumber :Bertzzie