Java - Rekursi: Panduan untuk Pemula

Hai di sana, ahli penyihir Java masa depan! Hari ini, kita akan menyelam ke dunia penyihir rekursi. Jangan khawatir jika ia terdengar seperti satu rakit penyihir dari Harry Potter – pada akhir tutorial ini, kamu akan melakukan rakit penyihir rekursif seperti seorang pro!

Java - Recursion

Apa itu Rekursi?

Bayangkan kamu sedang mencari rakus kering yang kau kalahkan di atas ruangan yang kacau. Kamu membuka rak, dan di dalamnya, ada rak yang lebih kecil. Kamu membukanya, dan tiba-tiba! Ada rak yang lebih kecil lagi di dalamnya. Proses pembukaan rak di dalam rak adalah sangat mirip dengan rekursi dalam pemrograman.

Dalam Java, rekursi adalah ketika satu metode memanggil dirinya sendiri untuk mengatasai masalah. Ia seperti metode tersebut mengatakan, "Saya tahu beberapa bagian dari solusi, tetapi untuk yang lainnya, saya akan bertanya kepada diri saya lagi!"

Cara Kerja Rekursi di Java?

Ayo pecahkan ia langkah demi langkah:

  1. Satu metode memanggil dirinya sendiri
  2. Ada kondisi untuk menghentikan rekursi (kasus dasar)
  3. Masalah dipecah menjadi sub-masalah yang lebih kecil dan serupa

Berikut adalah contoh sederhana:

public class RecursiveCountdown {
public static void countdown(int n) {
if (n == 0) {
System.out.println("Blast off!");
} else {
System.out.println(n);
countdown(n - 1);
}
}

public static void main(String[] args) {
countdown(5);
}
}

Dalam contoh ini, countdown adalah metode rekursif kami. Ia terus memanggil dirinya sendiri dengan angka yang lebih kecil sampai mencapai nol. Ayo lihat apa yang terjadi:

  1. countdown(5) mencetak 5, lalu memanggil countdown(4)
  2. countdown(4) mencetak 4, lalu memanggil countdown(3)
  3. Ini terus berlanjut sampai...
  4. countdown(0) mencetak "Blast off!" dan berhenti

Magik terjadi karena setiap pemanggilan ke countdown menunggu pemanggilan berikutnya selesai sebelum ia menyelesaikan. Ia seperti rak pancake – kita terus menambahkan (memanggil) sampai kita selesai, lalu kita makan (kembali) dari atas ke bawah.

Contoh Rekursi Java

Ayo lihat beberapa contoh lagi untuk benar-benar memahami berapa kuat rekursi bisa menjadi.

Contoh 1: Perhitungan Faktorial

Faktorial dari sebuah angka adalah hasil kali semua angka positif sampai angka itu. Misalnya, 5! (faktorial 5) adalah 5 4 3 2 1 = 120.

public class Factorial {
public static int factorial(int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}

public static void main(String[] args) {
System.out.println("Faktorial dari 5 adalah: " + factorial(5));
}
}

Cara kerjanya adalah:

  • factorial(5) mengembalikan 5 * factorial(4)
  • factorial(4) mengembalikan 4 * factorial(3)
  • Ini terus berlanjut sampai kita mencapai factorial(1), yang mengembalikan 1
  • Lalu kita kalikan kembali: 1 2 3 4 5 = 120

Contoh 2: Urutan Fibonacci

Urutan Fibonacci adalah sebuah seri di mana setiap angka adalah jumlah dari dua angka sebelumnya. Ia dimulai dengan 0 dan 1, lalu menjadi 1, 2, 3, 5, 8, 13, dan seterusnya.

public class Fibonacci {
public static int fibonacci(int n) {
if (n <= 1) {
return n;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}

public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.print(fibonacci(i) + " ");
}
}
}

Contoh ini sedikit trickier:

  • Untuk fibonacci(5), kita menghitung fibonacci(4) + fibonacci(3)
  • Setiap pemanggilan ini membuat dua pemanggilan lagi, dan seterusnya
  • Ia membentuk pohon pemanggilan, semua sampai ke fibonacci(0) dan fibonacci(1)
  • Lalu ia menambahkan semua hasil di atas saat kembali

Kelebihan Menggunakan Rekursi di Java

  1. Kesederhanaan: Solusi rekursif dapat lebih mudah untuk dipahami untuk beberapa masalah.
  2. Pengurangan ukuran kode: Kode rekursif dapat lebih ringkas.
  3. Mengatasi masalah kompleks: Beberapa masalah, seperti traversing pohon, secara alami rekursif.

Kekurangan Menggunakan Rekursi di Java

  1. Penggunaan memori: Setiap pemanggilan rekursif menambahkan ke stack pemanggilan, yang dapat menyebabkan stack overflow untuk rekursi yang dalam.
  2. Performa: Solusi rekursif dapat lebih lambat karena overhead pemanggilan fungsi banyak.
  3. Kesulitan dalam debugging: Menelusuri pemanggilan rekursif dapat menantang.

Kapan Menggunakan Rekursi

Rekursi menyinari ketika berurusan dengan masalah yang dapat dipecah menjadi sub-masalah yang serupa. Ia sangat baik untuk:

  • Traversing pohon
  • Algoritma graf
  • Algoritma divide dan conquer
  • Masalah backtracking

Rekursi vs Iterasi

Kadang-kadang, kamu dapat mengatasai masalah menggunakan rekursi atau iterasi (loop). Berikut adalah perbandingan cepat:

Aspek Rekursi Iterasi
Kesederhanaan Kode Banyak kali lebih sederhana untuk masalah kompleks Lebih sederhana untuk tugas yang langsung
Performa Dapat lebih lambat karena overhead pemanggilan fungsi Umumnya lebih cepat
Penggunaan Memori Dapat menggunakan lebih banyak memori (stack pemanggilan) Menggunakan lebih sedikit memori
Kepesutan Masalah Lebih baik untuk masalah dengan sifat rekursif Lebih baik untuk tugas berulang yang sederhana

Tips untuk Menulis Fungsi Rekursif

  1. Selalu memiliki kasus dasar: Ini adalah kondisi keluar kamu. Tanpa itu, kamu akan rekursif selamanya!
  2. Pastikan kemajuan menuju kasus dasar: Setiap pemanggilan rekursif harus membawa kamu lebih dekat ke kasus dasar.
  3. Percaya rekursi: Jangan coba untuk melacak semua pemanggilan di atas kepala kamu. Percayalah bahwa fungsi kamu akan bekerja untuk input yang lebih kecil.

Kesimpulan

Rekursi adalah seperti superpower dalam pemrograman. Mungkin memerlukan beberapa praktek untuk menguasai, tetapi sekali kamu melakukannya, kamu akan melihat masalah dalam cahaya baru. Ingat, setiap kali kamu menggunakan rekursi, kamu secara efektif membuat mesin waktu kecil di kode kamu, mengirimkan pesan ke versi masa lalu dan masa depan dari fungsi kamu. Berapa keren itu?

Terus latihan, dan segera kamu akan rekurs-ing lingkaran di sekitar masalah kompleks! Dan ingat, jika kamu pernah kesusahan di rekursi tak berakhir, cukup tekan ctrl+C untuk keluar – tak perlu mesin waktu! Selamat coding, masa depan master rekursi!

Credits: Image by storyset