You are on page 1of 45

Struktur Data & Algoritma

Rekursif

Suryana Setiawan, Ruli Manurung & Ade Azurat


(acknowledgments: Denny)

Fasilkom UI

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 1


Outline
 Lanjutan ADT dan Java Collection API
 Menggunakan Java Collection API
 Mengimplementasi abstract method
 Dasar-dasar Rekursif
 Apa itu recusion/rekursif?
 Aturan Rekursif
 Induksi Matematik

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 2


Tujuan
 Dapat menggunakan Java Collection API
 Memahami dasar-dasar rekursif

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 3


Lanjutan Java Collection API

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 4


Menggunakan Java Collection API
 Kapan kita perlu menggunakan Java Collection API?
 Saat kita memerlukan ADT dan ADT tersebut telah
disediakan oleh Java Collection API
 Bagaimana cara menggunakan Java Collection API?

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 5


Menggunakan Java Collection API
 Cari Class yang merupakan implementasi lengkap dari
ADT yang kita butuhkan.
Contoh:
 Kita membutuhkan ADT Stack.
 Java memiliki implementasi lengkap dari ADT Stack pada:
java.util.Stack
 Buat Object baru dengan new java.util.Stack(), atau
 Tuliskan di awal program: import java.util.Stack;
 atau: import java.util.*;

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 6


Menggunakan Java Collection API

 Bagaimana bila Java Collection API tidak miliki


implementasi lengkap dari sebuah ADT tapi :
 hanya memiliki interface-nya saja atau
 implementasi yang tersedia tidak sesuai dengan yang kita
inginkan.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 7


Menggunakan Java Collection API
 Kita harus mengidentifikasi interface-nya dan membuat
kelas baru yang meng-implement seluruh method yang
di sebutkan dalam interface tersebut.
 Untuk beberapa interface, Java Collection API menyediakan
abstract class yang dapat kita extends untuk meringankan
beban kita sehingga tak perlu mengimplement seluruh
method.
 Contoh:
• Misalkan kita ingin membuat implementasi sederhana dari
ADT set.
• Kita cukup mengextends abstract class AbstractSet
dan melengkapi method-method-nya.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 8


Contoh: Menggunakan ADT Set
 ADT Set adalah abstract data type yang tidak
mengizinkan adanya duplikasi dalam koleksi data.
 dalam Java Collection API, interface
java.util.Set adalah representasi dari ADT set.
 Dalam interface tersebut tidak terdapat implementasi,
melainkan hanya nama-nama method yang merupakan
interface untuk menggunakan ADT set.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 9


Contoh: Menggunakan ADT Set
 Interface Set tidak mendefinisikan method baru
dibanding parent interface Collection,
 Namun mengubah spesifikasi dari method:
 boolean add(E e)
 boolean addAll(Collection<? extends E> c)
 Kedua method tersebut hanya akan menambahkan data
bila tidak ada duplikasi.
 Return value: True, bila terjadi perubahan data (tidak
ada duplikasi)
 Return value: False, bila data sudah ada sebelumnya
(penambahan dapat menimbulkan duplikasi)

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 10


Contoh: Menggunakan ADT Set
 Interface Set tidak menyediakan implementasi
 Abstract Class AbstractSet hanya menyediakan
implementasi dari tiga methods:
 boolean equals(Object o)
 int hashCode()
 boolean removeAll(Collection<?> c)
 Class dengan implementasi lengkap antara lain adalah:
HashSet, TreeSet, dan EnumSet.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 11


Technical detail:

Bagaimana duplikasi bisa dihindari dalam


ADT Set?

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 12


Technical detail:
 Duplikasi dideteksi dengan menggunakan method equals
yang diturunkan dari kelas Object.
 Elemen dari koleksi Set harus memiliki definisi equals
yang masuk akal.
 Seringkali sekedar menggunakan default implementasi tidak
cukup dan tidak sesuai dengan yang kita inginkan.
 Contoh
 Set<DataMhs>, elemen-nya adalah class DataMhs.
 Kita harus memiliki definisi equals yang tepat untuk DataMhs,
 yaitu misalnya nama dan tanggal lahir harus unik.
 Definisi equals berdasarkan nama saja tidak cukup.
 Definisi equals mengikut sertakan hobby tidak relevan.
SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 13
Technical detail: HashSet
 HashSet.
 Salah satu Implementasi interface Set
 Element perlu mendefinisian ulang (meng-override) method
hashCode().
 Secara umum (average), operasi pada hashCode adalah
O(1). (Konstan).

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 14


Technical detail: HashSet
 Mengimplementasikan ulang method:
equals dan hashCode.
 harus meng-override bukan overload.
(signature harus sama persis)
 Bayangkan method hashCode dibutuhkan untuk
memberikan 'petunjuk' kepada HashSet dimana
meletakkan data dalam memory.
 Lihat Studi kasus BasedClass dan DerivedClass
(Weiss, p.233)

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 15


Technical detail: HashSet
 Hubungan antara equals dan hashCode
 jika, x.equals(y), maka kita harus menjamin bahwa:
x.hashCode = y.hashCode
 jika, ! x.equals(y), maka kita sepantasnya menjamin
bahwa x.hashCode ≠ y.hashCode
 Bagaimana definisi equals yang baik?
 Bagaimana definisi hashCode yang baik?
 Kita akan mempelajari lebih dalam mengenai
hashCode dalam kuliah selanjutnya.
 Untuk sementara ini, lihat contoh berikut:

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 16


Contoh: equals dan hashCode (1)

Class
Class StudentData{
StudentData{
String
String studentID,
studentID, firstName,
firstName, lastName,
lastName, address;
address;

public
public boolean
boolean equals(Object
equals(Object x){
x){
if
if (x
(x ==
== null
null ||
|| x.getClass()
x.getClass() !=
!= getClass())
getClass())
return
return false;
false;
}}

public
public int
int hashCode(){
hashCode(){
return
return Integer.parseInt(studentID);
Integer.parseInt(studentID);
}}
}}

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 17


Contoh: equals dan hashCode (2)
Class
Class StudentData{
StudentData{
String
String studentID,
studentID, firstName,
firstName, lastName,
lastName, address;
address;

public
public boolean
boolean equals(Object
equals(Object x){
x){
return
return studentID.equals
studentID.equals
(((StudentData)x).studentID);
(((StudentData)x).studentID);
}}

public
public int
int hashCode(){
hashCode(){
return
return firstName.length()
firstName.length()
++ lastName.length()
lastName.length()
++ address.length();
address.length();
}}
}}

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 18


Contoh: Menggunakan HashSet
import
import java.util.HashSet;
java.util.HashSet;
import
import java.util.Iterator;
java.util.Iterator;
import
import java.util.Set;
java.util.Set;

public
public class
class SetTester{
SetTester{
public
public static
static void
void main(String[]
main(String[] args)
args) {{
Set<String>
Set<String> mySet
mySet == new
new HashSet<String>();
HashSet<String>();
for(int
for(int ii=0;
ii=0; ii<args.length;
ii<args.length; ii++)
ii++)
mySet.add(args[ii]);
mySet.add(args[ii]);
Iterator<String>
Iterator<String> myIterator
myIterator == mySet.iterator();
mySet.iterator();
while(myIterator.hasNext())
while(myIterator.hasNext())
System.out.println(myIterator.next());
System.out.println(myIterator.next());
}}
}}

Apa output berikut ini?


java SetTester this is a very very very funny test

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 19


Technical detail: SortedSet
 Interface Set memiliki subinterface salah satunya:
SortedSet.
 Interface SortedSet, menjaga agar elemen dalam
koleksi terurut.
 Object Iterator akan menjamin elemen dalam
SortedSet akan dibaca secara berurut.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 20


Technical detail: SortedSet
 Method tambahan dalam interface SortedSet, antara
lain:
 E first()
Memberikan elemen pertama (terkecil) dalam set.
 E last()
Memberikan elemen terakhir (terbesar) dalam set.
 SortedSet<E> subSet(E x, E y)
Memberikan sub set antara x dan y.
 SortedSet<E> headSet(E x)
Memberikan bagian set yang elemennya lebih kecil (<) dari
pada x.
 SortedSet<E> tailSet(E x)
Memberikan bagian set yang elemennya lebih besar (>) dari
pada x.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 21


Bagaimana elemen dapat terurut
dalam SortedSet?

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 22


Technical Detail: Comparable
 Elemen sebuah SortedSet haruslah mengimplement
Interface Comparable.
 Lebih detail lagi, harus mengimplement method:
public int compareTo(E x)
 Sebagaimana Set umumnya, duplikasi dideteksi
dengan method equals.
 Dua buah elemen e1 dan e2 dianggap sama bila:
e1.compareTo(e2)==0
 Maka definisi equals dan compareTo,
harus konsisten!

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 23


Technical detail: TreeSet
 Salah satu implementasi dari SortedSet adalah kelas
: TreeSet
 Secara umum, rata-rata operasi pada TreeSet adalah
O(log n), namun worst case adalah O(n).

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 24


Contoh: TreeSet
import
import java.util.Iterator;
java.util.Iterator;
import
import java.util.SortedSet;
java.util.SortedSet;
import
import java.util.TreeSet;
java.util.TreeSet;
public
public class
class SortedSetTester{
SortedSetTester{
public
public static
static void
void main(String[]
main(String[] args){
args){
SortedSet<String>
SortedSet<String> mySortedSet
mySortedSet ==
new
new TreeSet<String>();
TreeSet<String>();
for(int
for(int ii=0;
ii=0; ii<args.length;
ii<args.length; ii++)
ii++)
mySortedSet.add(args[ii]);
mySortedSet.add(args[ii]);
Iterator<String>
Iterator<String> myIterator
myIterator ==
mySortedSet.iterator();
mySortedSet.iterator();
while(myIterator.hasNext())
while(myIterator.hasNext())
System.out.println(myIterator.next());
System.out.println(myIterator.next());
}}
}}
Apa output berikut ini?
java SetTester this is a very very very funny test
SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 25
Dasar-dasar Rekursif

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 26


Apa itu Rekursif?
 Method yang memanggil dirinya sendiri baik secara
langsung maupun secara tidak langsung.
 f(0) = 0; f(x) = 2 f(x-1) + x2
• f(1) = 1; f(2) = 6; f(3) = 21; f(4) = 58
 fib(n) = fib(n - 1) + fib(n - 2)

public
public static
static int
int ff (int
(int x)
x)
{{
if
if (x
(x ==
== 0)
0) return
return 0;
0;
return
return 22 ** ff (x
(x -- 1)
1) ++ xx ** x;
x;
}}

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 27


Method/Fungsi Recursion
 Fungsi yang memanggil dirinya, secara langsung atau
lewat fungsi lain, disebut fungsi rekursif
 Proses pemanggilan diri itu disebut rekursi
(recursion).
 Contoh:
 Memangkatkan bilangan real tak nol dengan suatu pangkat
bilangan bulat

1 jika n=0
x n=
{x∗x
1
x
n−1

−n
jika n0
jika n0

SUR – HMM – AA Fasilkom UI - IKI20100/ 28


/**
/**
/**
Menghitung pangkat sebuah bilangan real
Menghitung
Menghitung pangkat
pangkat sebuah
sebuah bilangan
bilangan real
real
(versi rekursif).
(versi
(versi rekursif).
rekursif).
@param x bilangan yang dipangkatkan (x != 0)
@param
@param xx bilangan
bilangan yang
yang dipangkatkan
dipangkatkan (x
(x !=
!= 0)
0)
@param n pangkatnya
@param
@param nn pangkatnya
pangkatnya
*/
*/
*/
public static
public
public static
static double
double pangkatRekursif
pangkatRekursif (double
(double x,x, int
int n)
n)
double pangkatRekursif (double x, int n)
{{
{
if
if (n
(n ==
== 0)
0) {{
if (n == 0) {
return
return 1.0;
1.0;
return 1.0;
}} else
else if
if (n
(n >> 0)
0) {{
} else if (n > 0) {
return
return (x(x ** pangkatRekursif
pangkatRekursif (x,
(x, nn -- 1));
1));
return (x * pangkatRekursif (x, n - 1));
}} else
else {{
} else {
return
return (1(1 // pangkatRekursif
pangkatRekursif (x,
(x, -n));
-n));
return (1 / pangkatRekursif (x, -n));
}}
}
}}
}
SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 29
Berapa nilai pangkat 4-2?
0.0625

pangkatRekursif (4.0, -2)


return (1 / pangkatRekursif (4.0, 2));

Returning values
16.0
Recursive calls

pangkatRekursif (4.0, 2)
return (4.0 * pangkatRekursif (4.0, 1));
4.0
pangkatRekursif (4.0, 1)
return (4.0 * pangkatRekursif (4.0, 0));

1.0
pangkatRekursif (4.0, 0)
return 1.0;

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 30


Algoritme Rekursif
 Ciri masalah yang dapat diselesaikan secara rekursif
adalah masalah itu dapat di-reduksi menjadi satu atau
lebih masalah-masalah serupa yang lebih kecil
 Secara umum, algoritme rekursif selalu mengandung
dua macam kasus:
 kasus induksi: satu atau lebih kasus yang pemecahan masalahnya
dilakukan dengan menyelesaikan masalah serupa yang lebih
sederhana (yaitu menggunakan recursive calls)
 kasus dasar atau kasus penyetop (base case): satu atau lebih kasus
yang sudah sederhana sehingga pemecahan masalahnya tidak perlu
lagi menggunakan recursive-calls.
 Supaya tidak terjadi rekursi yang tak berhingga, setiap
langkah rekursif haruslah mengarah ke kasus penyetop
(base case).

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 31


Aturan Rekursif
1. Punya kasus dasar
 Kasus yang sangat sederhana yang dapat memproses input
tanpa perlu melakukan rekursif (memanggil method) lagi
2. Rekursif mengarah ke kasus dasar
3. Percaya.
Pada proses pemanggilan rekursif, asumsikan bahwa
pemanggilan rekursif (untuk problem yang lebih kecil)
adalah benar.
 Contoh: pangkatRekursif (x, n)
• Asumsikan: pangkatRekursif (x, n - 1)
menghasilkan nilai yang benar.
• Nilai tersebut harus diapakan sehingga menghasilkan nilai
pangkatRekursif (x, n) yang benar?
• Jawabannya: dikalikan dengan x
4. Aturan penggabungan: Hindari duplikasi
pemanggilan rekursif untuk sub-problem yang
SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 32
Infinite Recursion

public
public static
static int
int bad
bad (int
(int n)
n)
{{
if
if (n
(n ==
== 0)
0) return
return 0; 0;
return
return bad
bad (n
(n ** 33 -- 1)
1) ++ nn -- 1;
1;
}}

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 33


How it works?
 Java VM menggunakan internal stack of activation
records
 Activation record dapat dilihat sebagai kertas yang
berisi informasi tentang method
 nilai parameter
 variabel lokal
 program counter (PC)

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 34


How it works?
 Ketika suatu method G dipanggil, sebuah activation
record untuk G dibuat dan di-push ke dalam stack;
saat ini G adalah method yang sedang aktif
 Ketika method G selesai (return), stack di-pop;
method dibawah G yang dipanggil.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 35


Too Much Recursion

public
public static
static long
long ss (int
(int n){
n){
if
if (n
(n ==
== 1)
1) {{
return
return 1;1;
}} else
else {{
return
return ss (n(n -- 1)
1) ++ n;
n;
}}
}}

 Di sebuah system, n >= 9410 tidak dapat dieksekusi

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 36


Pembuktian dgn Induksi
 Contoh kasus: pangkatRekursif (x,n)
 Buktikan bahwa base case benar.
 pangkatRekursif (x,0) = 1
 Buktikan bahwa inductive case benar
 Perhitungan/proses untuk input yang lebih kecil dapat
diasumsikan memberikan jawaban yang benar atau
melakukan proses dengan benar.
• asumsikan bahwa pangkatRekursif (x, n-1)
memberikan nilai xn-1
 apakah pangkatRekursif (x, n) mengembalikan
nilai yang benar?
• pangkatRekursif (x, n) =
pangkatRekursif (x, n-1) * x
• xn = xn-1 * x

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 37


Bilangan Fibonacci
 F0 = 0, F1 = 1, FN = FN-1 + FN-2
 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

public
public static
static int
int fib1
fib1 (int
(int n)
n)
{{
if
if (n
(n <=
<= 1)
1) return
return n;n;
return
return fib1
fib1 (n
(n –– 1)
1) ++ fib1
fib1 (n
(n –– 2);
2);
}}
SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 38
Bilangan Fibonacci
 Untuk N = 40, FN melakukan lebih dari 300 juta
pemanggilan rekursif. F40 = 102.334.155
 Analisa algoritme, Growth rate: exponential!!!
 Aturan: Jangan membiarkan ada duplikasi proses yang
mengerjakan input yang sama pada pemanggilan
rekursif yang berbeda. (Aturan ke-4)

 Ide: simpan nilai fibonacci yang sudah dihitung dalam


sebuah array

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 39


Bilangan Fibonacci

 Dynamic Programming menyelesaikan sub-


permasalahan dengan menyimpan hasil sebelumnya.
public
public static
static int
int fib2
fib2 (int
(int n){
n){
if
if (n
(n <=
<= 1)
1) return
return n;n;
int
int result[]
result[] == new
new int[n
int[n ++ 1];
1];
result[0]
result[0] == 0;
0;
result[1]
result[1] == 1;
1;
for
for (int
(int ii
ii == 2;
2; ii
ii <=
<= n;
n; ii++)
ii++) {{
result[ii]
result[ii] == result[ii
result[ii -- 2]
2]
++ result[ii
result[ii -- 1];1];
}}
return
return result[n];
result[n];
}}

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 40


Bilangan Fibonacci
 Hanya menyimpan dua hasil sebelumnya saja.

public
public static
static int
int fib3
fib3 (int
(int n){
n){
if
if (n
(n <=
<= 1)
1) return
return n;
n;

int
int fib1
fib1 == 0;
0;
int
int fib2
fib2 == 1;
1;
int
int result;
result;
for
for (int
(int ii
ii == 2;
2; ii
ii <=
<= n;
n; ii++)
ii++) {{
result
result == fib2
fib2 ++ fib1;
fib1;
fib1
fib1 == fib2;
fib2;
fib2
fib2 == result;
result;
}}
return
return result;
result;
}}

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 41


Bilangan Fibonacci
 Implementasi rekursif yang lebih efficient.
 Pendekatan Tail Recursive.

public
public static
static long
long fib4
fib4 (int
(int n){
n){
return
return fiboHelp(0,1,n);
fiboHelp(0,1,n);
}}

static
static long
long fiboHelp(long
fiboHelp(long x,
x, long
long y,
y, int
int n){
n){

if
if (n==0)
(n==0) return
return x;
x;
else
else if
if (n==1)
(n==1) return
return y;
y;
else
else return
return fiboHelp(y,
fiboHelp(y, x+y,
x+y, n-1);
n-1);
}}

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 42


Kesalahan Umum
 Base case terlalu kompleks
 Progress tidak menuju base case
 Duplikasi proses untuk nilai input yang sama dalam
recursive call yang terpisah. Tidak efisien.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 43


Ringkasan
 Method rekursif adalah method yang memanggil
dirinya sendiri baik secara langsung maupun secara
tidak langsung.
 Aturan Rekursif
 Definisikan base case: yang dapat memproses input tanpa
perlu recursive lagi
 Pada bagian rekursif pastikan akan bergerak menuju base
case.
 Asumsikan bahwa pemanggilan rekursif terhadap sub
problem berjalan benar.
 hindari duplikasi proses untuk nilai input yang sama dalam
recursive call yang terpisah.
 Bila memungkinkan lakukan tail recursive.

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 44


What’s Next
 Lanjutan Rekursif
 Devide and Conquer
 Backtracking
 Latihan Rekursif

SUR – HMM – AA Fasilkom UI - IKI20100/ Semester Ganjil – 2008/2009 45

You might also like