Recursion

Rekursi adalah teknik pemrograman di mana fungsi memanggil dirinya sendiri untuk menyelesaikan masalah.

Contoh Masalah

Bagaimana cara menyelesaikan masalah yang memiliki pola berulang? Misalnya:

  1. Menghitung faktorial
  2. Mencari bilangan Fibonacci
  3. Menjelajahi struktur data bersarang

Penyelesaian

package main

import "fmt"

// 1. Faktorial dengan rekursi
func factorial(n int) int {
    if n <= 1 {
        return 1
    }
    return n * factorial(n-1)
}

// 2. Fibonacci dengan rekursi
func fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return fibonacci(n-1) + fibonacci(n-2)
}

// 3. Fibonacci dengan memoization
func fibonacciMemo(n int, memo map[int]int) int {
    if val, exists := memo[n]; exists {
        return val
    }
    
    if n <= 1 {
        return n
    }
    
    memo[n] = fibonacciMemo(n-1, memo) + fibonacciMemo(n-2, memo)
    return memo[n]
}

// 4. Menghitung pangkat dengan rekursi
func power(base, exp int) int {
    if exp == 0 {
        return 1
    }
    return base * power(base, exp-1)
}

// 5. Mencari GCD (Greatest Common Divisor)
func gcd(a, b int) int {
    if b == 0 {
        return a
    }
    return gcd(b, a%b)
}

func main() {
    // Contoh 1: Faktorial
    fmt.Println("Faktorial:")
    for i := 0; i <= 5; i++ {
        fmt.Printf("%d! = %d\n", i, factorial(i))
    }

    // Contoh 2: Fibonacci
    fmt.Println("\nFibonacci (rekursi biasa):")
    for i := 0; i < 10; i++ {
        fmt.Printf("Fib(%d) = %d\n", i, fibonacci(i))
    }

    // Contoh 3: Fibonacci dengan memoization
    fmt.Println("\nFibonacci (dengan memoization):")
    memo := make(map[int]int)
    for i := 0; i < 10; i++ {
        fmt.Printf("Fib(%d) = %d\n", i, fibonacciMemo(i, memo))
    }

    // Contoh 4: Pangkat
    fmt.Println("\nPangkat:")
    fmt.Printf("2^3 = %d\n", power(2, 3))
    fmt.Printf("3^4 = %d\n", power(3, 4))

    // Contoh 5: GCD
    fmt.Println("\nGCD (Greatest Common Divisor):")
    fmt.Printf("GCD(48, 18) = %d\n", gcd(48, 18))
    fmt.Printf("GCD(54, 24) = %d\n", gcd(54, 24))
}

Penjelasan Kode

  1. Base Case

    • Kondisi berhenti rekursi
    • Mencegah infinite recursion
    • Mengembalikan nilai langsung
  2. Recursive Case

    • Memanggil fungsi sendiri
    • Mengurangi masalah
    • Menggabungkan hasil
  3. Optimisasi

    • Memoization untuk performa
    • Tail recursion
    • Stack overflow consideration

Output

Faktorial:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120

Fibonacci (rekursi biasa):
Fib(0) = 0
Fib(1) = 1
Fib(2) = 1
Fib(3) = 2
Fib(4) = 3
Fib(5) = 5
Fib(6) = 8
Fib(7) = 13
Fib(8) = 21
Fib(9) = 34

Fibonacci (dengan memoization):
Fib(0) = 0
Fib(1) = 1
Fib(2) = 1
Fib(3) = 2
Fib(4) = 3
Fib(5) = 5
Fib(6) = 8
Fib(7) = 13
Fib(8) = 21
Fib(9) = 34

Pangkat:
2^3 = 8
3^4 = 81

GCD (Greatest Common Divisor):
GCD(48, 18) = 6
GCD(54, 24) = 6

Tips

  • Selalu definisikan base case
  • Perhatikan stack overflow
  • Gunakan memoization untuk optimasi
  • Pertimbangkan solusi iteratif
  • Rekursi bagus untuk masalah yang bisa dipecah