Kuliah

Cara Menghitung Big O dari Kode: Loop Bersarang sampai Log n

Delapan contoh soal Big O dari kode Python: loop berurutan, bersarang segitiga, i *= 2, sampai rekurensi T(n) = 2T(n/2) + n, lengkap dengan hitungan iterasinya.

Oleh Diterbitkan 5 Nov 2026 9 menit baca
Di halaman ini

Big O dari sebuah kode dihitung dengan cara menghitung berapa kali operasi paling dalam dijalankan sebagai fungsi dari nn, lalu membuang konstanta dan suku yang tumbuhnya lebih lambat. Loop berurutan dijumlahkan, loop bersarang dikalikan, dan loop yang variabelnya dikali atau dibagi 2 menghasilkan log⁡n\log n. Delapan contoh soal di bawah melatih ketiga aturan itu, masing-masing dengan jumlah iterasi yang bisa kamu cek sendiri.

Tiga aturan dasarnya:

  1. Berurutan dijumlah. Dua blok yang ditulis satu setelah yang lain memakan f(n)+g(n)f(n) + g(n) langkah. Ambil yang terbesar.
  2. Bersarang dikali. Loop di dalam loop memakan (iterasi luar) kali (iterasi dalam), asalkan loop dalam tidak bergantung pada variabel luar. Kalau bergantung, jumlahkan satu per satu.
  3. Buang konstanta dan suku kecil. 3n2+5n+23n^2 + 5n + 2 ditulis O(n2)O(n^2). Konstanta 3 dan suku 5n5n tidak mengubah bentuk pertumbuhan.

Contoh di bawah memakai Python, tapi logikanya sama untuk C, Java, atau pseudocode. Yang dihitung adalah berapa kali baris c += 1 dijalankan.

Soal 1 sampai 4: loop tunggal, berurutan, dan bersarang

Soal 1. Loop tunggal

for i in range(n):
    c += 1

Badan loop jalan tepat nn kali. Jawaban: O(n)O(n). Kalau loopnya range(0, n, 2), iterasinya ⌈n/2⌉\lceil n/2 \rceil (untuk nn genap tepat n/2n/2), dan tetap O(n)O(n) karena faktor 12\frac{1}{2} adalah konstanta.

Soal 2. Dua loop berurutan

for i in range(n):
    c += 1
for j in range(n):
    c += 1

Totalnya n+n=2nn + n = 2n langkah. Jawaban: O(n)O(n), bukan O(n2)O(n^2). Dua loop yang tidak bersarang tidak dikalikan.

Soal 3. Bersarang penuh

for i in range(n):
    for j in range(n):
        c += 1

Untuk setiap ii, loop dalam jalan nn kali. Totalnya n⋅n=n2n \cdot n = n^2. Jawaban: O(n2)O(n^2).

Soal 4. Bersarang segitiga

for i in range(n):
    for j in range(i):
        c += 1

Loop dalam bergantung pada ii, jadi tidak bisa langsung dikali. Saat i=0i = 0 loop dalam jalan 0 kali, saat i=1i = 1 jalan 1 kali, dan seterusnya sampai n−1n - 1:

0+1+2+⋯+(n−1)=n(n−1)2=12n2−12n0 + 1 + 2 + \cdots + (n-1) = \frac{n(n-1)}{2} = \frac{1}{2}n^2 - \frac{1}{2}n

Untuk n=16n = 16, hasilnya 16⋅152=120\frac{16 \cdot 15}{2} = 120, dan kalau kodenya dijalankan, c memang berakhir di 120. Suku dominannya n2n^2, jadi jawaban: O(n2)O(n^2). Loop segitiga memang kira-kira setengah lebih cepat dari soal 3, tapi kelas pertumbuhannya sama.

Soal 5 dan 6: dari mana log n muncul?

Soal 5. Variabel dikali 2

i = 1
while i < n:
    i *= 2
    c += 1

Nilai ii berjalan 1,2,4,8,…1, 2, 4, 8, \ldots dan berhenti begitu i≥ni \ge n. Setelah kk iterasi, i=2ki = 2^k. Loop berhenti saat 2k≥n2^k \ge n, yaitu k=⌈log⁡2n⌉k = \lceil \log_2 n \rceil. Untuk n=1000n = 1000, nilai ii yang dilewati adalah 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, total 10 iterasi, dan ⌈log⁡21000⌉=10\lceil \log_2 1000 \rceil = 10. Jawaban: O(log⁡n)O(\log n).

Hal yang sama berlaku untuk i //= 2 yang dimulai dari nn, dan untuk binary search yang membuang separuh data tiap langkah.

Soal 6. Luar linear, dalam logaritmik

for i in range(n):
    j = 1
    while j < n:
        j *= 2
        c += 1

Loop dalam tidak bergantung pada ii, jadi aturan kali berlaku: n⋅⌈log⁡2n⌉n \cdot \lceil \log_2 n \rceil. Untuk n=16n = 16, hasilnya 16⋅4=6416 \cdot 4 = 64. Jawaban: O(nlog⁡n)O(n \log n).

Basis logaritma tidak ditulis di dalam Big O. Alasannya, log⁡2n=log⁡10nlog⁡102\log_2 n = \frac{\log_{10} n}{\log_{10} 2}, dan 1log⁡102\frac{1}{\log_{10} 2} hanyalah konstanta.

Soal 7 dan 8: jebakan yang membuat jawaban meleset

Soal 7. Loop dalam bergantung pada m

for i in range(n):
    for j in range(m):
        c += 1

Banyak mahasiswa langsung menulis O(n2)O(n^2). Padahal ada dua input yang berbeda, misalnya nn baris dan mm kolom sebuah matriks. Jawaban yang benar: O(n⋅m)O(n \cdot m). Jawaban ini baru boleh disederhanakan menjadi O(n2)O(n^2) kalau soal menyatakan m=nm = n.

Soal 8. Bersarang tapi linear

i = n
while i > 0:
    for j in range(i):
        c += 1
    i //= 2

Ada loop di dalam loop, dan loop luar jalan sekitar log⁡2n\log_2 n kali, jadi godaannya menjawab O(nlog⁡n)O(n \log n). Hitung saja isinya: loop dalam jalan nn kali, lalu n2\frac{n}{2}, lalu n4\frac{n}{4}, dan seterusnya.

n+n2+n4+⋯+1<2nn + \frac{n}{2} + \frac{n}{4} + \cdots + 1 < 2n

Untuk n=16n = 16, totalnya 16+8+4+2+1=3116 + 8 + 4 + 2 + 1 = 31, di bawah 2⋅16=322 \cdot 16 = 32. Jawaban: O(n)O(n). Soal ini menunjukkan kenapa aturan "bersarang dikali" hanya berlaku kalau loop dalam punya panjang tetap.

Rangkuman jawaban dan seberapa besar bedanya

SoalPolaIterasi tepatBig O
1Loop tunggalnnO(n)O(n)
2Dua loop berurutan2n2nO(n)O(n)
3Bersarang penuhn2n^2O(n2)O(n^2)
4Bersarang segitigan(n−1)2\frac{n(n-1)}{2}O(n2)O(n^2)
5i *= 2⌈log⁡2n⌉\lceil \log_2 n \rceilO(log⁡n)O(\log n)
6Luar nn, dalam j *= 2n⌈log⁡2n⌉n \lceil \log_2 n \rceilO(nlog⁡n)O(n \log n)
7Luar nn, dalam mmnmnmO(nm)O(nm)
8Dalam mengecil separuh<2n< 2nO(n)O(n)

Supaya terasa bedanya, ini jumlah langkah untuk tiga ukuran input:

nnlog⁡2n\log_2 nnlog⁡2nn \log_2 nn2n^2
103,333100
1.00010,0sekitar 10 ribu1 juta
1.000.00019,9sekitar 20 juta101210^{12}

Di nn sejuta, algoritma O(nlog⁡n)O(n \log n) butuh sekitar 20 juta langkah, sedangkan O(n2)O(n^2) butuh sejuta juta. Itu alasan sorting di tracing bubble, selection, dan insertion sort terasa lambat untuk data besar dibanding merge sort.

Kesalahan yang paling sering saat menghitung Big O

  • Menjumlah padahal harus mengalikan. Soal 3 dijawab O(2n)O(2n) karena "ada dua loop". Dua loop bersarang dikalikan.
  • Mengalikan padahal harus menjumlah. Kebalikannya, soal 2 dijawab O(n2)O(n^2). Lihat indentasinya: kalau loop kedua tidak berada di dalam loop pertama, jumlahkan.
  • Menyertakan konstanta. O(2n)O(2n), O(n/2)O(n/2), dan O(3n2+5)O(3n^2 + 5) bukan jawaban yang salah secara matematis, tapi hampir semua dosen akan mengurangi nilai karena bentuknya belum disederhanakan. Tulis O(n)O(n) dan O(n2)O(n^2).
  • Menyamakan semua loop bersarang dengan n2n^2. Soal 7 dan 8 menunjukkan dua cara loop bersarang tidak menghasilkan n2n^2.
  • Menghitung satu iterasi sebagai satu langkah padahal isinya memanggil fungsi. Kalau badan loop memanggil sorted(data) atau x in daftar, operasi itu sendiri bukan O(1)O(1). Pencarian in pada list Python adalah O(n)O(n), jadi loop nn kali yang berisi in menjadi O(n2)O(n^2).

Cara membuktikan Big O dengan konstanta C dan n0

Definisi formalnya: f(n)=O(g(n))f(n) = O(g(n)) kalau ada konstanta positif CC dan n0n_0 sehingga f(n)≤C⋅g(n)f(n) \le C \cdot g(n) untuk semua n≥n0n \ge n_0. Soal pembuktian biasanya meminta kamu menemukan pasangan CC dan n0n_0 itu.

Contoh: buktikan f(n)=3n2+5n+2f(n) = 3n^2 + 5n + 2 adalah O(n2)O(n^2).

Cara cepat: untuk n≥1n \ge 1, berlaku n≤n2n \le n^2 dan 1≤n21 \le n^2. Ganti setiap suku dengan batas atasnya:

3n2+5n+2≤3n2+5n2+2n2=10n23n^2 + 5n + 2 \le 3n^2 + 5n^2 + 2n^2 = 10n^2

Jadi C=10C = 10 dan n0=1n_0 = 1 memenuhi definisi. Selesai.

Pasangan itu tidak unik. Kalau kamu ingin CC lebih kecil, misalnya C=4C = 4, syaratnya menjadi 3n2+5n+2≤4n23n^2 + 5n + 2 \le 4n^2, atau n2−5n−2≥0n^2 - 5n - 2 \ge 0. Akar positifnya 5+332≈5,37\frac{5 + \sqrt{33}}{2} \approx 5{,}37, jadi n0=6n_0 = 6. Cek: di n=6n = 6, ruas kiri 108+30+2=140108 + 30 + 2 = 140 dan ruas kanan 144144, benar. Di n=5n = 5, ruas kiri 102102 dan ruas kanan 100100, gagal. Pembuktian dengan C=4,n0=6C = 4, n_0 = 6 sama sahnya dengan C=10,n0=1C = 10, n_0 = 1.

Rekurensi T(n) = 2T(n/2) + n sebagai jembatan ke teorema master

Begitu kode memanggil dirinya sendiri, menghitung loop tidak lagi cukup. Merge sort adalah contoh klasik: fungsi membagi data jadi dua, memanggil dirinya untuk tiap separuh, lalu menggabungkan hasilnya dalam nn langkah. Waktu jalannya ditulis sebagai rekurensi:

T(n)=2T(n2)+n,T(1)=1T(n) = 2T\left(\frac{n}{2}\right) + n, \qquad T(1) = 1

Cara paling mudah memahaminya adalah pohon rekursi. Gambar berikut untuk n=8n = 8.

Pohon rekursi T(n) = 2T(n/2) + n untuk n = 8: setiap level berbiaya 8, ada tiga level pembagian ditambah level daun, total 32

Setiap level punya biaya total nn, karena jumlah simpul berlipat dua sementara ukurannya mengecil separuh. Banyaknya level pembagian adalah log⁡2n\log_2 n, ditambah satu level daun yang berisi nn kasus dasar. Totalnya:

T(n)=nlog⁡2n+nT(n) = n \log_2 n + n

Cek dengan menghitung manual: T(2)=2⋅1+2=4T(2) = 2 \cdot 1 + 2 = 4, T(4)=2⋅4+4=12T(4) = 2 \cdot 4 + 4 = 12, T(8)=2⋅12+8=32T(8) = 2 \cdot 12 + 8 = 32. Rumus memberi 8⋅3+8=328 \cdot 3 + 8 = 32. Cocok. Jadi T(n)=O(nlog⁡n)T(n) = O(n \log n).

Teorema master memberi jawaban yang sama tanpa menggambar. Untuk bentuk T(n)=aT(n/b)+f(n)T(n) = aT(n/b) + f(n), di sini a=2a = 2, b=2b = 2, dan nlog⁡ba=n1=nn^{\log_b a} = n^1 = n. Karena f(n)=nf(n) = n tumbuh sama cepat dengan nlog⁡ban^{\log_b a}, rekurensi masuk kasus kedua dan hasilnya Θ(nlog⁡n)\Theta(n \log n). Kasus pertama dan ketiga berlaku kalau f(n)f(n) jelas lebih lambat atau lebih cepat dari nlog⁡ban^{\log_b a}. Rekursi yang lebih sederhana, seperti faktorial dan Fibonacci, dibahas langkah demi langkah di rekursi Python dan tracing call stack.

FAQ

Apa beda Big O, Big Omega, dan Big Theta?

Big O adalah batas atas, Big Omega batas bawah, dan Big Theta berarti keduanya sekaligus. Soal 3 adalah Θ(n2)\Theta(n^2) karena jumlah langkahnya tepat n2n^2. Menulis O(n3)O(n^3) untuk soal 3 secara teknis tidak salah, tapi tidak informatif, sehingga di tugas kamu diminta batas yang paling ketat.

Apakah Big O sama dengan kasus terburuk?

Tidak persis. Big O adalah notasi untuk batas atas sebuah fungsi, sedangkan kasus terburuk, rata-rata, dan terbaik adalah tiga fungsi berbeda. Insertion sort, misalnya, punya kasus terbaik O(n)O(n) untuk data yang sudah urut dan kasus terburuk O(n2)O(n^2) untuk data terbalik. Kalau soal tidak menyebut, biasanya yang diminta kasus terburuk.

Kenapa O(1) tetap O(1) walaupun isinya 100 baris?

Karena jumlah langkahnya tidak bergantung pada nn. Loop for i in range(100) jalan 100 kali, baik datanya berisi 10 maupun sejuta elemen. Konstanta sebesar apa pun ditulis O(1)O(1).

Bagaimana menghitung Big O kode dengan if-else?

Ambil cabang yang paling mahal. Kalau cabang if berisi loop O(n)O(n) dan cabang else berisi satu perintah O(1)O(1), seluruh blok dihitung O(n)O(n) untuk kasus terburuk.

Apakah O(n log n) selalu lebih cepat dari O(n²)?

Untuk nn besar, ya. Untuk nn sangat kecil, konstanta yang dibuang Big O bisa membuat algoritma O(n2)O(n^2) menang. Itu sebabnya beberapa implementasi sorting di bahasa pemrograman memakai insertion sort untuk potongan data yang pendek.

Artikel Terkait

Siap taklukkan UTS, UAS, dan skripsi?