Kodnos
Software Engineering

Zaman Karmasikligi ve Big O Notasyonu

Big O notasyonu nedir ve neden onemlidir? Interaktif grafikler, Python ve Java kod ornekleri ve durumlarin %90'ini kapsayan basit zihinsel model ile pratik bir rehber.

A
admin
6 Mar 20266 dk okuma17 görüntülenme
Zaman Karmasikligi ve Big O Notasyonu

Big O Nedir? (Ve Neden Önemsemelisiniz?)

Bir itirafla başlayayım: "Big O notasyonu"nu ilk duyduğumda, sadece bilgisayar bilimi profesörlerinin umursadığı ileri düzey bir matematik konusu olduğunu düşünmüştüm. Spoiler — yanılmışım. Hem de çok.

Big O notasyonu, kodunuzun girdi büyüdükçe nasıl yavaşladığını tanımlamanın basit bir yoludur. Hepsi bu. Ne daha fazla, ne daha az.

Şöyle düşünün: 10 elemanla mükemmel çalışan bir fonksiyon yazıyorsunuz. Harika. Ama patronunuz "artık 10 milyon kullanıcımız var" dediğinde ne olacak? Fonksiyonunuz hâlâ milisaniyeler içinde çalışacak mı? Yoksa tıkanıp kalacak mı?

İşte Big O tam olarak bunu söyler. Şu sorunun cevabıdır: "Kodum ölçeklendiğinde nasıl davranır?"

Gerçek Dünyada Neden Önemli

Şöyle gerçek bir senaryo gördüm. Bir geliştirici, iç içe döngüler kullanarak bir arama fonksiyonu yazıyor. 100 elemanla test sırasında gayet güzel çalışıyor. Sonra 100.000 elemanla canlıya çıkıyor. Sayfa 47 saniyede yükleniyor. Kullanıcılar gidiyor. Para kaybediliyor.

Eğer o geliştirici Big O'yu anlasaydı, O(n²) çözümünün saatli bir bomba olduğunu bilir ve bunun yerine hash map'e (O(1) arama) yönelirdi.

Big O akademik teori değildir. Canlıda gerçekten çalışan kod yazmak için hayatta kalma becerisidir.

Her Şeyi Basitleştiren Tek Kural

Big O'nun güzel tarafı şu — her bir işlemi saymanıza gerek YOK. Sadece baskın terimi belirleyin ve gerisini atın:

  • O(3n + 500)O(n) — sabitler ölçekte önemli değil
  • O(n² + 5n + 100)O(n²) — en büyük terim kazanır
  • O(500)O(1) — sabit sayıda adım her zaman sabittir
  • Neden? Çünkü Big O, ölçekteki davranışı tanımlar. n küçükken her şey hızlıdır. n devasa olduğunda sadece baskın terim önemlidir.

    Uygulamada Görün

    Aşağıdaki interaktif grafik, 6 yaygın karmaşıklığı birlikte gösteriyor. Her birini adım adım görmek için oynat tuşuna basın veya okları kullanın:

    <iframe src="/tr/dsa/embed.html?topic=0&lang=tr" width="100%" height="200" style="border:none;border-radius:12px;overflow:hidden" loading="lazy"></iframe>


    Her Karmaşıklığı Parçalayalım (Gerçek Örneklerle)

    Şimdi en hızlıdan en yavaşa, her karmaşıklık sınıfını inceleyelim. Her biri için ne anlama geldiğini, nerede gördüğünüzü ve neden önemli olduğunu açıklayacağım.

    O(1) — Sabit Zaman: Kutsal Kase

    Ne anlama gelir: Girdiniz ne kadar büyük olursa olsun — 10 eleman veya 10 milyar eleman — işlem aynı sürede tamamlanır.

    Nerede görürsünüz: İndeksle dizi erişimi, hash map aramaları, yığına eleman ekleme.

    Neden önemli: Bir problemi O(1)'de çözebiliyorsanız, kazandınız demektir.

    O(log n) — Logaritmik: İnanılmaz Hızlı

    Ne anlama gelir: Her adımda kalan iş yarıya iner. 1 milyon eleman? Yaklaşık 20 adım. 1 milyar eleman? Yaklaşık 30 adım.

    Nerede görürsünüz: İkili arama, dengeli ikili ağaç işlemleri.

    Neden önemli: Pratikte O(1)'e neredeyse eşittir.

    O(n) — Doğrusal: Adil ve Dürüst

    Ne anlama gelir: Süre doğrudan girdiyle büyür. 10 eleman = 10 adım. 1 milyon eleman = 1 milyon adım.

    Nerede görürsünüz: Diziyi bir kez tarama, max/min bulma, eleman sayma.

    Neden önemli: Her elemana bakmanız gerekiyorsa, O(n) en iyidir. Temel çizgidir.

    O(n log n) — Doğrusal-Logaritmik: Sıralamanın Tatlı Noktası

    Ne anlama gelir: Doğrusallığın biraz üstünde. n elemanın her biri için log n işlem yapılır.

    Nerede görürsünüz: Merge sort, quick sort, heap sort.

    Neden önemli: Karşılaştırma tabanlı sıralama için teorik sınırdır.

    O(n²) — Karesel: Sessiz Katil

    Ne anlama gelir: Süre, girdinin karesiyle büyür. 10 eleman = 100 adım. 1.000 eleman = 1.000.000 adım.

    Nerede görürsünüz: İç içe döngüler, bubble sort, selection sort.

    Neden önemli: Küçük girdilerde sorunsuz ama n büyüdükçe patlıyor.

    O(2ⁿ) — Üstel: Kaçın

    Ne anlama gelir: Her ek eleman toplam işi İKİYE KATLAR. 10 eleman = 1.024 adım. 20 eleman = 1 milyondan fazla.

    Nerede görürsünüz: Tüm alt kümeleri oluşturma, memoizasyonsuz özyinelemeli Fibonacci.

    Neden önemli: n < 25 garanti değilse, her ne pahasına olursa olsun kaçının.


    Kod Örnekleri

    Python

    Python
    # O(1) - Sabit: tek bir erişim, döngü yok
    def get_first(arr: list):
        return arr[0] if arr else None

    # O(n) - Doğrusal: tek döngü def find_max(arr: list) -> int: max_val = arr[0] for num in arr: # n kez if num > max_val: max_val = num return max_val

    # O(n²) - Karesel: iç içe döngüler = n × n def has_duplicate(arr: list) -> bool: for i in range(len(arr)): # n kez for j in range(i + 1, len(arr)): # × n kez if arr[i] == arr[j]: return True return False

    Java

    Java
    // O(1) - Sabit: doğrudan dizi erişimi
    public static int getFirst(int[] arr) {
        return arr[0];
    }

    // O(n) - Doğrusal: tek döngü public static int findMax(int[] arr) { int max = arr[0]; for (int num : arr) { // n kez if (num > max) max = num; } return max; }

    // O(n²) - Karesel: iç içe döngüler public static boolean hasDuplicate(int[] arr) { for (int i = 0; i < arr.length; i++) { // n kez for (int j = i + 1; j < arr.length; j++) { // × n kez if (arr[i] == arr[j]) return true; } } return false; }


    Herhangi Bir Kodun Karmaşıklığını Belirleme

    1. Döngüleri sayın. Döngü yok = O(1). Tek döngü = O(n). İki iç içe = O(n²). 2. Veriyi yarılıyor mu? Her iterasyon işi yarıya indiriyorsa O(log n). 3. Özyinelemeye bakın. Kendini iki kez çağırıyorsa muhtemelen O(2ⁿ). 4. Sabitleri atın. O(3n + 10) = O(n). O(n² + n) = O(n²). 5. Adlandırın. O(1) sabit, O(log n) logaritmik, O(n) doğrusal, O(n²) karesel, O(2ⁿ) üstel.


    Pratik Problemler

  • Two Sum — O(n²) yerine O(n)'de yapabilir misiniz?
  • Binary Search — Klasik O(log n) algoritması
  • Contains Duplicate — O(n²) kaba kuvvet ile O(n) hash set karşılaştırması
  • Maximum Subarray — Kadane algoritması O(n) başarır
  • Merge Sort — Böl-ve-fethet'in neden O(n log n) verdiğini anlayın

  • Sonuç

    Big O, kulağa korkutucu gelen ama aslında sezgiyi yakaladığınızda basit olan kavramlardan biridir:

  • O(1) anlık. O(log n) neredeyse anlık. O(n) adil. O(n log n) sıralamanın en iyisi. O(n²) tehlikeli. O(2ⁿ) felaket.
  • Döngüleri sayın. Sabitleri atın. En büyük terimi tutun.
  • Kodunuz yavaşsa ilk soru: "Bunun Big O'su ne?"

Bir sonraki yazıda alan karmaşıklığından bahsedeceğiz. Çünkü tüm RAM'inizi yiyen hızlı kod, yavaş koddan iyi değildir. Orada görüşürüz.

6 DkBu makaleyi paylaşın
Oğuzhan Berke Özdil
Yazar

Oğuzhan Berke Özdil

Çocukluğumdan beri bilgisayarlarla iç içeyim. Bu sitede, yazılımı daha sağlam temellerle öğrenme yolculuğumda edindiğim bilgi ve deneyimleri paylaşıyorum. AGH University of Krakow'da Bilgisayar Bilimleri lisansımı tamamladım ve şu anda aynı üniversitede AI & Data Analysis odaklı yüksek lisansıma devam ediyorum.

Yorumlar (