9. Fungsi Rekursif

PHP Dasar: Fungsi Rekursif (3/3)

Pada pertemuan kali ini, yang akan kita pelajari adalah mengenai fungsi rekursif.

Apa itu Fungsi Rekursif?

Kita telah menyinggung tentang fungsi rekursif pada pembahasan konsep perulangan pada PHP.

Fungsi rekursif adalah metode perulangan yang terjadi akibat pengeksekusian suatu fungsi yang mana fungsi tersebut memanggil dirinya sendiri. Bisa jadi ia terus memanggil dirinya sendiri tanpa batas, atau mungkin dia akan berhenti jika kondisi tertentu terpenuhi.

Ilustrasinya adalah: seperti anda memiliki 2 buah cermin. Anda letakkan kedua cermin tersebut sedemikian rupa hingga saling berhadapan. Lalu anda coba berdiri di depannya, dan ya! Anda akan melihat pantulan diri anda tidak terbatas.

Ilustrasi yang lainnya adalah: PC anda sedang di-remote oleh PC lain. Lalu anda meremote PC yang sedang meremote PC anda, al-hasil anda akan melihat PC anda berkali-kali tanpa ujung seperti pada gambar berikut:

Gambar 2: ilustrasi fungsi rekursif. Sumber gambar: link.

Pendeklarasian Fungsi Rekursif

Tidak ada cara khusus dalam pendeklarasian fungsi rekursif. Ia hanyalah fungsi biasa. Sama saja apakah ia adalah fungsi yang mengembalikan sebuah nilai atau tidak.

Yang membedakan adalah: ia akan memanggil dirinya sendiri sehingga terjadilah suatu perulangan.

Contoh:

<?php

function tampilkanHaloDunia () {
  echo "Halo dunia! <br>";

  tampilkanHaloDunia();
}

# panggil fungsi tampilkanHaloDunia();
tampilkanHaloDunia();

Jika kode program di atas dijalankan, ia akan menampilkan teks “Halo dunia!" sebanyak tak terbatas.

Dan ia tentu saja akan membuat komputer anda hank. Jadi, jangan coba-coba dilakukan, ya!

Menampilkan Angka 1-100

Untuk menampilkan angka 1 sampai 100, kita bisa dengan mudah menggunakan perulangan for seperti berikut:

<?php

for ($i = 1; $i <= 100; $i++) {
  echo "Perulangan ke-{$i} <br>";
}

Akan tetapi jika anda ingin menggunakan konsep fungsi rekursif untuk menjalankan tugas yang sama, anda perlu sedikit berfikir.

Pertama, anda buat fungsinya dulu, fungsi biasa.

<?php

function tampilkanAngka ($i) {
  echo "Perulangan ke-{$i} <br>";
}

Jika anda memanggil fungsi tampilkanAngka() di atas, fungsi tersebut hanya akan menampilkan teks sebanyak satu kali saja.

Sekarang, kita jadikan ia sebagai fungsi rekursif.

Kita beri 2 parameter tambahan, yaitu parameter $jumlah untuk mengetahui berapa jumlah perulangan yang akan dilakukan, dan yang kedua adalah parameter $indeks untuk mengetahui sekarang sudah perulangan ke berapa.

Untuk parameter $indeks kita beri nilai default dengan angka 1.

<?php

function tampilkanAngka (int $jumlah, int $indeks = 1) {
  echo "Perulangan ke-{$indeks} <br>";

  # panggil diri sendiri selama $indeks <= $jumlah
  if ($indeks < $jumlah) {
    tampilkanAngka($jumlah, $indeks + 1);
  }
}

Lalu panggil fungsi tampilkanAngka dengan memasukkan satu parameter saja yaitu parameter $jumlah.

<?php

tampilkanAngka(20);

Perhatikan alur perjalanan program

Sekarang untuk menguji pemahaman, kita coba balik kode program pada fungsi tampilkanAngka.

Jika kita melakukan proses rekursif setelah perintah echo, sekarang kita balik: kita lakukan proses rekursif terlebih dahulu, setelah itu kita lakukan perintah echo.

Seperti ini:

<?php

function tampilkanAngka (int $jumlah, int $indeks = 1) {
  # panggil diri sendiri selama $indeks <= $jumlah
  if ($indeks < $jumlah) {
    tampilkanAngka($jumlah, $indeks + 1);
  }

  echo "Perulangan ke-{$indeks} <br>";
}

Coba panggil fungsi tampilkanAngka() tersebut, lalu cek bagaimana output yang dihasilkan.

Kita mendapatkan output terbalik bukan?

Perulangan ke-20
Perulangan ke-19
Perulangan ke-18
Perulangan ke-17
...
Perulangan ke-4
Perulangan ke-3
Perulangan ke-2
Perulangan ke-1

Itu terjadi karena:

  1. Ketika fungsi tampilkanAngka dipanggil pertama kali, ia akan langsung memanggil dirinya sendiri.
  2. Ketika ia dipanggil untuk ke-2 kalinya, ia juga langsung memanggil dirinya sendiri.
  3. Ia terus melakukan hal yang sama sampai nilai $indeks = nilai $jumlah alias bernilai 20.
  4. Baru setelah rantai paling akhir tidak lagi memanggil dirinya sendiri, ia akan mulai menampilkan angka 20.
  5. Setelah rantai paling akhir selesai menampilkan angka 20, maka proses yang ke-19 pun dianggap telah selesai dari proses rekursif, dan ia akan mulai meng-echo angka 19.
  6. Begitu seterusnya hingga kembali ke perulangan yang pertama.

Masih agak bingung?

Kalau masih agak bingung, silakan ubah kode program di atas menjadi seperti ini:

<?php

function tampilkanAngka (int $jumlah, int $indeks = 1) {
  echo "<strong style='color: green'>
    Sebelum memanggil diri sendiri [{$indeks}]
  </strong><br>";
 
  # panggil diri sendiri selama $indeks <= $jumlah
  if ($indeks < $jumlah) {
    tampilkanAngka($jumlah, $indeks + 1);
  } else {
    echo "<strong style='color: red'>
      Proses terakhir.
    </strong><br>";
  }

  echo "<strong style='color: blue'>
    Sebelum memanggil diri sendiri [{$indeks}]
  </strong><br>";
}

Sekarang saya hanya panggil dengan parameter $jumlah = 5 agar tidak terlalu outputnya lebih ringkas:

<?php

tampilkanAngka(5);

Output:

Berikut ini adalah output yang saya hasilkan:

Sampai sini, sudah mulai jelas bagaimana proses dan alur fungsi rekursif bekerja.

Contoh Kasus Faktorial

Selanjutnya kita coba contoh kasus paling populer dalam penggunakan metode perulangan rekursif.

Kasus tersebut adalah kasus pemecahan faktorial. Dimana faktorial dari n sama dengan n * faktorial(n-1).

Misalkan faktorial dari angka 5, maka kita bisa sederhanakan caranya seperti ini:

faktorial(5) = 5 * faktorial(4)
faktorial(4) = 4 * faktorial(3)
faktorial(3) = 3 * faktorial(2)
faktorial(2) = 2 * faktorial(1)
faktorial(1) = 1

Hasil di atas sama dengan:

faktorial 5 = 5 * 4 * 3 * 2 * 1
# hasil = 120

Penyelesaian

Dengan rumus seperti di atas, kita bisa mulai memecahkannya dengan fungsi rekursif.

Kita mulai dulu fungsinya secara sederhana seperti berikut:

<?php

function faktorial ($n) {
  echo "faktorial({$n}) = faktorial(" . ($n - 1) . ") <br>";

  if ($n > 2) {
    faktorial($n - 1);
  }
}

# panggil
faktorial(5);

Ia akan menghasilkan output:

faktorial(5) = faktorial(4)
faktorial(4) = faktorial(3)
faktorial(3) = faktorial(2)
faktorial(2) = faktorial(1)

Setelah kita berhasil mendapatkan perulangan yang benar, kita ubah fungsi faktorial di atas dengan mengembalikan suatu nilai seperti berikut:

<?php

function faktorial ($n) {
  if ($n > 2) {
    return $n * faktorial($n - 1);
  } else {
    return $n;
  }
}

# lalu panggil fungsi faktorial
$hasil = faktorial(5);
echo $hasil;

Jika anda menjalankan program di atas lalu output hasilnya adalah 120, berarti program anda telah berjalan dengan benar.

Silakan ubah parameter $n untuk memeriksa apakah memang fungsi faktorial yang anda lakukan memang betul-betul berfungsi seperti yang diinginkan.

Contoh Kasus Menu Bertingkat Tak Terbatas

Di bawah ini saya memiliki variabel $menu. Ia adalah gabungan antara array terindeks dan array asosiatif multidimensi. Dikatakan multidimensi karena ia adalah suatu array yang memiliki array lain di dalamnya.

Untuk penjelasan lebih lanjut silakan lihat pembahasan tentang array multidimensi.

Silakan perhatikan kode program di bawah. Karena selanjutnya kita akan coba menampilkan semua item dari array $menu menggunakan fungsi rekursif.

<?php

$menu = [
  [
    "nama" => "Beranda"
  ],
  [
    "nama" => "Berita",
    "subMenu" => [
      [
        "nama" => "Olahraga",
        "subMenu" => [
          [
            "nama" => "Bola"
          ],
          [
            "nama" => "Bulu Tangkis"
          ]
        ]
      ],
      [
        "nama" => "Politik"
      ],
      [
        "nama" => "Manca Negara"
      ]
    ]
  ],
  [
    "nama" => "Tentang"
  ],
  [
    "nama" => "Kontak"
  ],
];

Pertama kita buat dulu fungsi untuk menampilkan array utama.

<?php

function tampilkanMenuBertingkat (array $menu) {
  echo "<ul>";
  foreach ($menu as $key => $item) {
    echo "<li>{$item['nama']}</li>";
  }
  echo "</ul>";
}

Jika kita panggil fungsi di atas:

<?php

tampilkanMenuBertingkat($menu);

Kita akan dapatkan hasil seperti ini:

  • Beranda
  • Berita
  • Tentang
  • Kontak

Sekarang kita buat fungsi di atas menjadi rekursif dengan memanggil dirinya sendiri ketika suatu item dari menu memiliki attribut subMenu.

<?php

function tampilkanMenuBertingkat (array $menu) {
  echo "<ul>";
  foreach ($menu as $key => $item) {
    echo "<li>{$item['nama']}</li>";

    # periksa apakah ia memiliki atribut subMenu
    # dan apakah attribut tersebut memiliki isi
    if (@$item['subMenu'] && count($item['subMenu'])) {
      # jika ia panggil diri sendiri
      tampilkanMenuBertingkat($item['subMenu']);
    }
  }
  echo "</ul>";
}

Kita coba jalankan lagi dan… ya! Kita berhasil mendapatkan hasil seperti ini:

  • Beranda
  • Berita
    • Olahraga
      • Bola
      • Bulu Tangkis
    • Politik
    • Manca Negara
  • Tentang

Anda bisa mengubah-ubah variabel $nama untuk mencoba apakah memang fungsi rekursif yang kita buat tersebut sudah berfungsi dengan benar.

Pembahasan Selanjutnya

Dengan selesainya tutorial ini, berarti kita telah selesai dengan pembahasan Fungsi pada PHP.

Pada pembahasan selanjutnya, kita akan membahas tentang memanipulasi string lalu setelahnya akan membahas bekerja dengan array. Insyaallah.

Jika anda merasa seri tutorial php dasar ini bermanfaat, silakan bagikan kepada yang lainnya.

Terima kasih banyak!