Bölüm 1: Giriş

Algoritmalar
Algoritma nedir?Algoritma analiziO, Ω ve Θ gösterimleriKarmaşıklık sınıfları Araya ekleyerek sıralamaBirleştirerek sıralamaİkili arama ve üs almaEuclid algoritması
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Algoritma

Algoritmanın tanımını ve özelliklerini (girdi, çıktı, açıklık, sonluluk, etkinlik) açıklamak; günlük bir işi algoritma olarak yazmak.

Analiz

Çalışma süresini girdi boyutu n'nin fonksiyonu T(n) olarak ifade etmek; en kötü, ortalama ve en iyi durumu ayırt etmek.

Gösterimler

O, Ω ve Θ gösterimlerinin üst, alt ve sıkı sınır anlamını kavramak; bir koddan karmaşıklık sınıfını (1, log n, n, n log n, n², n³, 2ⁿ, n!) okumak.

Temel algoritmalar

Araya ekleyerek sıralama, birleştirme, ikili arama, hızlı üs alma ve Euclid algoritmasını adım adım izlemek ve yineleme bağıntılarını kurmak.

Algoritma Kavramı

Algoritma Nedir?

  • Bir problemi çözmek veya bir görevi yerine getirmek için izlenen adım adım yönergeler dizisidir.
  • Girdi verileri alınır, işlemler yapılır, çıktı elde edilir.
  • Her adım belirli, açık ve anlaşılır olmalı; algoritma sınırlı sayıda adımda sonlanmalıdır.
Girdi (input)Sıfır veya daha fazla değer dışarıdan alınır.
Çıktı (output)En az bir sonuç üretilir; sonuç girdiyle ilişkilidir.
AçıklıkHer adımın tek bir anlamı vardır; yoruma yer bırakmaz.
SonlulukHer girdi için sonlu sayıda adımdan sonra durur.
EtkinlikHer adım temel ve gerçekten yapılabilir bir işlemdir.
DoğrulukHer geçerli girdi için doğru çıktıyı verir.

Algoritma Kavramı

Günlük Hayattan: Çay Hazırlama Algoritması

Girdi: su, çay yaprakları, şeker (isteğe bağlı), süt (isteğe bağlı)
Çıktı: çay

  1. Suyu kaynat.
  2. Kaynamış suyu demliğe koy.
  3. Demliğin içine çay yapraklarını ekle.
  4. Çayın demlenmesini bekle.
  5. Demlenen çayı fincana süzerek koy.
  6. İsteğe bağlı olarak şeker ve süt ekle.
Sıra önemlidirAdım 2 ile 3'ün yeri değişebilir, ama 1 ile 5'in yeri değişemez: algoritma bir sıralı adımlar listesidir.
Açık mı?"Demlenmesini bekle" ne kadar? Bir bilgisayar için adım şöyle olmalıdır: 10 dakika bekle.
KararAdım 6 bir koşul içerir: "şeker isteniyorsa ekle". Algoritmalar karar noktaları da içerir.

Algoritma Kavramı

Ortalama Bulma: Algoritmadan Koda

AlgoritmaGirdi: Sayı1, Sayı2, Sayı3 · Çıktı: Ortalama
1. Toplam = Sayı1 + Sayı2 + Sayı3
2. Ortalama = Toplam / 3
3. Ortalama değerini ekrana yazdır.

Python

def ortalama_hesapla(sayi1, sayi2, sayi3):
    ortalama = (sayi1 + sayi2 + sayi3) / 3
    return ortalama

sayi1 = float(input("Birinci sayıyı girin: "))
sayi2 = float(input("İkinci sayıyı girin: "))
sayi3 = float(input("Üçüncü sayıyı girin: "))
ort = ortalama_hesapla(sayi1, sayi2, sayi3)
print("Girilen sayıların ortalaması:", ort)

Java

public static void main(String[] args) {
  Scanner giris = new Scanner(System.in);
  System.out.println("Birinci sayıyı girin: ");
  double sayi1 = giris.nextDouble();
  System.out.println("İkinci sayıyı girin: ");
  double sayi2 = giris.nextDouble();
  System.out.println("Üçüncü sayıyı girin: ");
  double sayi3 = giris.nextDouble();
  double ortalama = (sayi1 + sayi2 + sayi3) / 3;
  System.out.println("Sayıların ortalaması: "
                     + ortalama);
}

Aynı algoritma farklı dillerde yazılabilir: algoritma dilden bağımsızdır, program onun bir gerçekleştirimidir.

Algoritma Kavramı

Algoritmalar Nerede? Başlıca Türler

SıralamaElemanları bir düzene koyar: araya ekleyerek, birleştirerek, hızlı sıralama. (Bölüm 2)
AramaBir elemanı bulur: doğrusal ve ikili arama, hash. (Bölüm 3)
ÇizgeEn kısa yol (Dijkstra), en küçük kapsayan ağaç, maksimum akış (Ford–Fulkerson). (Bölüm 4)
Dizgi ve sıkıştırmaMetin arama, trie; dosya boyutunu küçültme: Huffman, gzip. (Bölüm 5)
Tasarım teknikleriBöl ve fethet, dinamik programlama, açgözlü, geri dönüşlü, dal-sınır. (Bölüm 6, 11–14)
Rastgele ve yaklaşıkAynı girdide farklı yol izleyebilen rastgele algoritmalar; zor problemlere yaklaşık çözüm. (Bölüm 7–8)
Deterministik algoritma aynı girdi için her zaman aynı adımları izler ve aynı çıktıyı verir (ör. en büyük elemanı bulma). Rastgele (randomized) algoritma zar atar: hızlı sıralamada pivotu rastgele seçmek gibi.

Algoritma Analizi

Algoritma Analizi

  • Bir algoritmanın performansını anlamak ve değerlendirmek için kullanılır.
  • İşlemci ve bellek gibi kaynakların verimli kullanılmasını sağlar.
  • Zaman analizi: algoritmanın çalışma süresini ölçer; genellikle Big-O gösterimiyle yazılır.
  • Bellek analizi: algoritmanın ek bellek kullanımını (bellek karmaşıklığı) değerlendirir.
  • Aynı problemi çözen algoritmalar arasında seçim yapmamızı sağlar.
Neden önemli?10⁶ elemanlı sıralı bir dizide arama:
doğrusal arama → en kötü 1.000.000 karşılaştırma
ikili arama → en fazla 20 karşılaştırma
Bellek örnekleriEn büyük elemanı bulma: O(1) ek bellek.
Birleştirerek sıralama: O(n) yardımcı dizi.
Özyineleme: çağrı yığını kadar bellek.

Algoritma Analizi

Zaman Karmaşıklığı

  • Bir algoritmanın çalışma süresini girdi boyutu n ile ilişkilendiren kavramdır: T(n).
  • Saniye değil, temel işlem sayısı sayılır: saniye bilgisayara ve dile göre değişir, işlem sayısı değişmez.
  • Veri büyüdükçe performansın nasıl değiştiğini inceler; bir algoritmanın iyi ya da kötü olduğunu belirlemede kritik faktördür.

Örnek: n elemanlı dizinin toplamı, satır satır sayım

int toplam = 0;                   // 1 kez
for (int i = 0; i < n; i++)       // n+1 karşılaştırma
  toplam += dizi[i];              // n kez
return toplam;                    // 1 kez
T(n) = 1 + (n + 1) + n + 1 = 2n + 3. Sabitler makineye bağlıdır; önemli olan T(n)'nin n ile doğrusal büyümesidir → Θ(n).

Algoritma Analizi

Fonksiyonların Büyüme Hızları

00101020203030404050506060707080809090100100n (girdi boyutu)işlem sayısıFonksiyonn!2ⁿn²n log₂ nn√nlog₂ n1

n = 10'da bile n! (3,6 milyon) ve 2ⁿ (1024) grafiğin dışına çıkar; log₂ n ve √n ise n = 100'de hâlâ 10'un altındadır.

Algoritma Analizi

Büyüme Tablosu: n Büyürken

f(n)n = 10n = 100n = 1000n = 10⁶süre (n = 10⁶)
111111 ns
log₂ n3,36,610,019,919,9 ns
√n3,21031,61.0001 µs
n101001.0001.000.0001 ms
n log₂ n33,2664,49.9662,0 · 10⁷19,9 ms
n²10010.0001.000.0001,0 · 10¹²16,7 dk
2ⁿ1.0241,3 · 10³⁰≈ 1,1 · 10³⁰¹≈ 10³⁰¹⁰³⁰evrenin yaşından çok
n!3.628.8009,3 · 10¹⁵⁷≈ 10²⁵⁶⁷≈ 10⁵⁵⁶⁵⁷⁰⁸evrenin yaşından çok

Son sütun: saniyede 10⁹ temel işlem yapan bir bilgisayarda n = 10⁶ için tahmini süre. 2ⁿ ve n! için n = 100 bile (≈ 10³⁰ ve 10¹⁵⁸ işlem) pratikte çözülemez.

Daha hızlı bir bilgisayar sabiti küçültür; daha iyi bir algoritma büyüme hızını değiştirir. n² yerine n log n, 10⁶ elemanda dakikaları milisaniyelere indirir.

Algoritma Analizi

Deneyin: Büyüme Hesaplayıcı

f(n)işlem sayısı10⁹ işlem/s ile sürebağıl

"n × 2" düğmesiyle girdiyi ikiye katlayın: n sütunu 2 katına, n² 4 katına, n³ 8 katına çıkar; log₂ n yalnızca 1 artar, 2ⁿ ise karesini alır.

Algoritma Analizi

Asimptotik Gösterimler: O, Ω, Θ

Büyük O: üst sınırf(n) = O(g(n)): n ≥ n₀ için f(n) ≤ c·g(n). "En fazla bu kadar hızlı büyür."
n₀nf(n)c·g(n)
Süre 100 s ile sınırlıysa daha kısa sürebilir, ama daha uzun süremez.
Omega Ω: alt sınırf(n) = Ω(g(n)): n ≥ n₀ için f(n) ≥ c·g(n). "En az bu kadar hızlı büyür."
n₀nf(n)c·g(n)
Alt sınır 100 s ise daha uzun sürebilir, ama daha kısa süremez.
Theta Θ: sıkı sınırf(n) = Θ(g(n)): hem O(g(n)) hem Ω(g(n)). "Tam olarak bu hızda büyür."
n₀nf(n)c₂·g(n)c₁·g(n)
Doğrusal aramanın en kötü durumu: c₁·n ≤ T(n) ≤ c₂·n → Θ(n).
Dikkat: O, Ω, Θ sınır türleridir; en kötü / en iyi durum ile aynı şey değildir. Uygulamada O çoğunlukla en kötü durum süresi için kullanılır. Ayrıntılı tanım ve özellikler: Bölüm 1.2.

Karmaşıklık Örnekleri

Doğrusal Arama (Linear Search)

int dogrusalAra(int[] dizi, int aranan) {
  for (int i = 0; i < dizi.length; i++) {
    if (dizi[i] == aranan) {
      return i;  // bulundu!
    }
  }
  return -1;  // bulunamadı
}
Zaman karmaşıklığıEn kötü durumda (hedef yok ya da sonda) döngü n kez döner:
T(n) = c₁ · n + c₂
c₁ ve c₂ bilgisayarın hızı, programlama dili gibi etkenlere bağlıdır.
Θ(n)Süre, girdi boyutu n ile orantılı büyür: yeterince büyük n için bazı k₁, k₂ > 0 sabitleriyle
k₁ · n ≤ T(n) ≤ k₂ · n.
En iyi durum: hedef ilk eleman → 1 karşılaştırma, Θ(1).

Karmaşıklık Örnekleri

Sabit ve Doğrusal Zaman: O(1), O(n)

İlk elemanı yazdırma T(n) = O(1)

void ilkElemaniYazdir(int[] dizi) {
  if (dizi.length > 0)
    System.out.println("İlk eleman: "
                     + dizi[0]);
  else
    System.out.println("Dizi boş");
}

Dizi 10 elemanlı da olsa 10 milyon elemanlı da olsa tek karşılaştırma ve tek erişim yapılır: süre n'den bağımsızdır.

En büyük elemanı bulma T(n) = O(n)

Integer enBuyukBul(int[] dizi) {
  if (dizi.length == 0)
    return null;            // dizi boşsa
  int enBuyuk = dizi[0];
  for (int eleman : dizi)
    if (eleman > enBuyuk)
      enBuyuk = eleman;
  return enBuyuk;
}

Her eleman bir kez incelenir: n karşılaştırma. Ek bellek O(1). Örnek: [5, 8, 12, 4] → 12.

Karmaşıklık Örnekleri

Logaritmik Zaman: İkili Arama, O(log n)

int ikiliArama(int[] dizi, int aranan) {
  int alt = 0, ust = dizi.length - 1;
  while (alt <= ust) {
    int orta = (alt + ust) / 2;
    int tahmin = dizi[orta];
    if (tahmin == aranan)
      return orta;    // bulundu
    else if (tahmin < aranan)
      alt = orta + 1;
    else
      ust = orta - 1;
  }
  return -1;         // bulunamadı
}

Dizi sıralı olmalıdır. Her adımda aranan aralık yarıya iner: n → n/2 → n/4 → … → 1.

nen fazla adım
84
1.00010
1.000.00020
1,0 · 10⁹30

En fazla ⌊log₂ n⌋ + 1 adım → T(n) = O(log n). Adım adım örnek: Böl ve Fethet bölümünde.

Karmaşıklık Örnekleri

Asal Sayı Kontrolü: O(√n)

boolean asalMi(int n) {
  if (n <= 1)
    return false;
  else if (n == 2)
    return true;
  else if (n % 2 == 0)
    return false;
  int kokN = (int) Math.sqrt(n) + 1;
  for (int i = 3; i < kokN; i += 2)
    if (n % i == 0)
      return false;
  return true;
}
Neden √n'e kadar?n = a · b ise a ve b'den biri √n'den küçük ya da eşittir. √n'e kadar bölen yoksa n asaldır.
Kaç bölme?Çift sayılar baştan elenir; yalnızca tek i denenir: en fazla ≈ √n / 2 bölme → T(n) = O(√n).

n = 97: i = 3, 5, 7, 9 → 4 bölme (2'den 96'ya denense 95).
n = 1.000.000.007: 15.810 bölme.

Not: burada girdi boyutu n sayısının değeridir. Sayının bit uzunluğu b ise √n = 2b/2: bu yöntem bit sayısına göre üstel büyür.

Karmaşıklık Örnekleri

n log n Zaman: Çabuk (Hızlı) Sıralama

List<Integer> hizliSirala(List<Integer> liste) {
  if (liste.size() <= 1)
    return liste;
  int pivot = liste.get(0);
  List<Integer> kucukler = new ArrayList<>();
  List<Integer> buyukler = new ArrayList<>();
  for (int x : liste.subList(1, liste.size()))
    if (x <= pivot) kucukler.add(x);
    else buyukler.add(x);
  List<Integer> sonuc = hizliSirala(kucukler);
  sonuc.add(pivot);
  sonuc.addAll(hizliSirala(buyukler));
  return sonuc;
}

İlk eleman pivot; küçük-eşitler solda, büyükler sağda özyinelemeli sıralanır ve birleştirilir.

Ortalama: O(n log n)Pivot diziyi yaklaşık ikiye bölerse log₂ n düzey olur, her düzeyde toplam n karşılaştırma yapılır.
En kötü: O(n²)Dizi zaten sıralıysa ilk eleman hep en küçüktür; bölünme n−1 / 0 olur: (n−1) + (n−2) + … + 1 = n(n−1)/2.

Hızlı sıralamanın O(n log n) süresi ortalama durumdur; rastgele pivot seçimi en kötü durumu olası olmaktan çıkarır (Bölüm 2).

Karmaşıklık Örnekleri

Karesel Zaman: Kabarcık Sıralama, O(n²)

void kabarcikSirala(int[] dizi) {
  int n = dizi.length;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n - i - 1; j++)
      if (dizi[j] > dizi[j + 1]) {
        int gecici = dizi[j];    // takas
        dizi[j] = dizi[j + 1];
        dizi[j + 1] = gecici;
      }
}

Komşu elemanlar karşılaştırılır, sırasızsa takas edilir. Her dış turda en büyük eleman sona "kabarcık gibi" çıkar.

Sayımi. turda iç döngü n − i − 1 kez döner:
(n−1) + (n−2) + … + 1 + 0 = n(n−1)/2 karşılaştırma.

n = 1000 → 499.500 karşılaştırma; n iki katına çıkınca süre ≈ 4 katına çıkar. T(n) = O(n²).

Karmaşıklık Örnekleri

Kübik Zaman: Matris Çarpımı, Θ(n³)

int[][] matrisCarp(int[][] A, int[][] B) {
  int n = A.length, m = B[0].length, p = B.length;
  int[][] sonuc = new int[n][m];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      int eleman = 0;
      for (int k = 0; k < p; k++)
        eleman += A[i][k] * B[k][j];
      sonuc[i][j] = eleman;
    }
  return sonuc;
}

Girdi: A = [aᵢⱼ], B = [bᵢⱼ] (n × n). Çıktı: C = [cᵢⱼ] = A · B, i, j = 1, 2, …, n.

Tanımcᵢⱼ = Σk=1..n aᵢₖ · bₖⱼ
12
34
·
56
78
=
1922
4350

c₁₁ = 1·5 + 2·7 = 19. Her cᵢⱼ için n çarpma, n² eleman → n³ çarpma: T(n) = Θ(n³).

Karmaşıklık Örnekleri

Faktöriyel Zaman: Tüm Permütasyonları Üretme

void permutasyon(int[] dizi, int k) {
  if (k == dizi.length) {          // bir permütasyon hazır
    System.out.println(Arrays.toString(dizi));
    return;
  }
  for (int i = k; i < dizi.length; i++) {
    takas(dizi, k, i);             // i. elemanı k. konuma al
    permutasyon(dizi, k + 1);      // geri kalanları diz
    takas(dizi, k, i);             // eski hâline getir
  }
}

[1, 2, 3] → 123, 132, 213, 231, 321, 312. İlk konum için n, ikinci için n−1, … seçenek: n · (n−1) · … · 1 = n! permütasyon.

nn!
36
5120
103.628.800
151,3 · 10¹²
202,4 · 10¹⁸

Her permütasyonu yazmak n adım sürer: toplam Θ(n · n!), kısaca "O(n!) sınıfı". n = 20 bile pratikte imkânsızdır.

Karmaşıklık Örnekleri

Üstel Zaman: Fibonacci Serisi

long fib(int n) {           // saf özyineleme
  if (n <= 1) return n;
  return fib(n - 1) + fib(n - 2);
}

long[] bellek = new long[N + 1]; // 0: yok
long fibBellek(int n) {     // ezberleme
  if (n <= 1) return n;
  if (bellek[n] == 0)
    bellek[n] = fibBellek(n - 1) + fibBellek(n - 2);
  return bellek[n];
}

F(0) = 0, F(1) = 1, F(n) = F(n−1) + F(n−2).

nfib çağrısıfibBellek
5159
1017719
2021.89139
302.692.53759

fib: her çağrı iki çağrı doğurur → O(2ⁿ) (kesin olarak Θ(1,618ⁿ)).
fibBellek: her F(k) bir kez hesaplanır, 2n − 1 çağrı → O(n).

Karmaşıklık Örnekleri

Fibonacci: Çağrı Ağacı fib(5)

f5f4f3f2f1f0f1f2f1f0f3f2f1f0f1

Saf özyineleme: 15 çağrı. f3 iki kez, f2 üç kez, f1 beş kez hesaplanır; ağaç her düzeyde yaklaşık ikiye katlanır → üstel büyüme.

f5f4f3f2f1f0f1f2f3

Ezberlemeli: 9 çağrı. Turuncu kesikli düğümler (f2, f3) bellek dizisinden hazır döner, alt ağaçları hiç açılmaz → O(n).

Karmaşıklık Örnekleri

Karmaşıklık Sınıfları: Örneklerle

SınıfAdıÖrnekn iki katına çıkınca süre
O(1)sabitilk elemanı yazdırma, dizi erişimideğişmez
O(log n)logaritmikikili arama, hızlı üs alma, Euclid+1 adım
O(√n)karekökasal sayı kontrolü (deneme bölmesi)≈ 1,41 katı
O(n)doğrusaldoğrusal arama, en büyük eleman, birleştirme2 katı
O(n log n)doğrusal-logaritmikbirleştirerek sıralama, hızlı sıralama (ortalama)2 katından biraz fazla
O(n²)kareselkabarcık, araya ekleyerek sıralama4 katı
O(n³)kübikklasik matris çarpımı8 katı
O(2ⁿ)üstelsaf özyinelemeli Fibonacci, alt kümelerkaresi alınır
O(n!)faktöriyeltüm permütasyonlarçok daha hızlı patlar

Yukarıdan aşağıya büyüme hızı artar: 1 < log n < √n < n < n log n < n² < n³ < 2ⁿ < n!. Polinom sınıflar (nk) genelde "verimli", üstel olanlar "verimsiz" sayılır.

Araya Ekleyerek Sıralama

Sıralama Problemi

  • Girdi: n sayıdan oluşan dizi ⟨a₁, a₂, …, aₙ⟩.
  • Çıktı: aynı sayıların bir permütasyonu ⟨a′₁, a′₂, …, a′ₙ⟩ öyle ki a′₁ ≤ a′₂ ≤ … ≤ a′ₙ.
Girdi:824936Çıktı:234689
Neden sıralama?Arama (ikili arama sıralı dizi ister), tekrar bulma, sıralı rapor, birleştirme gibi pek çok işlemin ön adımıdır.
Örnek girdiBu bölüm boyunca aynı diziyi kullanacağız: 8 2 4 9 3 6. Bölüm 2'de pek çok sıralama algoritması karşılaştırılır.

Araya Ekleyerek Sıralama

Araya Ekleyerek Sıralama (Insertion Sort)

  • Diziyi sıralamak için iç içe iki döngü kullanır.
  • Dış döngü dizinin her elemanını bir kez geçer: A[i] anahtar değişkenine alınır.
  • İç döngü anahtardan büyük elemanları birer sağa kaydırır ve anahtarı uygun konuma yerleştirir.
  • İskambil kâğıtlarını elde sıralamak gibi: her yeni kâğıt, sıralı eldeki yerine sokulur.
A:0ijn−1anahtarsıralı kısım A[0..i−1]henüz işlenmemiş

Değişmez (invariant): her dış adımın başında A[0..i−1] sıralıdır. Zaman karmaşıklığı (en kötü) O(n²).

Araya Ekleyerek Sıralama

Araya Ekleyerek Sıralama: Kod

public void Sirala(int[] A) {
  for (int i = 1; i < A.length; ++i) {
    int anahtar = A[i];
    int j = i - 1;
    // A[0..i-1] alt dizisi sıralı.
    // anahtar uygun konuma yerleştirilir.
    while (j >= 0 && A[j] > anahtar) {
      A[j + 1] = A[j];
      j = j - 1;
    }
    A[j + 1] = anahtar;
  }
}
Dış döngü: n − 1 adımi = 1, 2, …, n−1. Her adımda bir eleman sıralı kısma eklenir.
İç döngü: en fazla i adımAnahtar, sıralı kısımdaki tüm elemanlardan küçükse (dizi tersten sıralıysa) i eleman kaydırılır.
Toplam (en kötü)1 + 2 + … + (n−1) = n(n−1)/2 → O(n²). Ek bellek O(1): yerinde (in-place) sıralar.

Araya Ekleyerek Sıralama

Örnek: 8 2 4 9 3 6

baş824936

Başlangıç: 8 tek başına sıralıdır (yeşil). Anahtar 2: 8'den küçük → 8 sağa kayar, 2 başa girer.

baş8249361.284936

1. ekleme sonrası: 2 8 4 9 3 6. Sıradaki anahtar 4: kendinden büyük 1 eleman sağa kayar, 1. konuma girer.

baş8249361.2849362.248936yerinde kalır

2. ekleme sonrası: 2 4 8 9 3 6. Sıradaki anahtar 9: solundaki 8'ten büyük, yerinde kalır.

baş8249361.2849362.248936yerinde kalır3.248936

3. ekleme sonrası: 2 4 8 9 3 6. Sıradaki anahtar 3: kendinden büyük 3 eleman sağa kayar, 1. konuma girer.

baş8249361.2849362.248936yerinde kalır3.2489364.234896

4. ekleme sonrası: 2 3 4 8 9 6. Sıradaki anahtar 6: kendinden büyük 2 eleman sağa kayar, 3. konuma girer.

baş8249361.2849362.248936yerinde kalır3.2489364.2348965.234689bitti

Son eleman da yerine girdi: 2 3 4 6 8 9 — sıralama bitti (n − 1 = 5 dış adım).

Araya Ekleyerek Sıralama · Kodu adım adım çalıştır

Sirala(A): Kodu Adım Adım İzle

802142933465

Dizi: 8 2 4 9 3 6. A[0] = 8 tek başına sıralı kabul edilir; dış döngü i = 1'den başlar.

802142933465ij2anahtar

i = 1: anahtar = A[1] = 2, j = 0. Sıralı kısım: 8.

808142933465ij=−12anahtar

A[0] = 8 > 2 → A[1] = A[0] (sağa kaydır), j = -1.

208142933465ij=−12anahtar

Koşul yanlış: j = −1 (başa gelindi). A[0] = anahtar = 2. A[0..1] sıralı: 2 8.

208142933465ij4anahtar

i = 2: anahtar = A[2] = 4, j = 1. Sıralı kısım: 2 8.

208182933465ij4anahtar

A[1] = 8 > 4 → A[2] = A[1] (sağa kaydır), j = 0.

204182933465ij4anahtar

Koşul yanlış: A[0] = 2 ≤ 4. A[1] = anahtar = 4. A[0..2] sıralı: 2 4 8.

204182933465ij9anahtar

i = 3: anahtar = A[3] = 9, j = 2. Sıralı kısım: 2 4 8.

204182933465ij9anahtar

Koşul yanlış: A[2] = 8 ≤ 9. A[3] = anahtar = 9. A[0..3] sıralı: 2 4 8 9.

204182933465ij3anahtar

i = 4: anahtar = A[4] = 3, j = 3. Sıralı kısım: 2 4 8 9.

204182939465ij3anahtar

A[3] = 9 > 3 → A[4] = A[3] (sağa kaydır), j = 2.

204182839465ij3anahtar

A[2] = 8 > 3 → A[3] = A[2] (sağa kaydır), j = 1.

204142839465ij3anahtar

A[1] = 4 > 3 → A[2] = A[1] (sağa kaydır), j = 0.

203142839465ij3anahtar

Koşul yanlış: A[0] = 2 ≤ 3. A[1] = anahtar = 3. A[0..4] sıralı: 2 3 4 8 9.

203142839465ij6anahtar

i = 5: anahtar = A[5] = 6, j = 4. Sıralı kısım: 2 3 4 8 9.

203142839495ij6anahtar

A[4] = 9 > 6 → A[5] = A[4] (sağa kaydır), j = 3.

203142838495ij6anahtar

A[3] = 8 > 6 → A[4] = A[3] (sağa kaydır), j = 2.

203142638495ij6anahtar

Koşul yanlış: A[2] = 4 ≤ 6. A[3] = anahtar = 6. A[0..5] sıralı: 2 3 4 6 8 9.

203142638495

i = 6 = A.length → döngü biter. Sonuç: 2 3 4 6 8 9. Toplam 11 karşılaştırma, 7 kaydırma.

public void Sirala(int[] A) {
  for (int i = 1; i < A.length; ++i) {
    int anahtar = A[i];
    int j = i - 1;
    // A[0..i-1] sıralı
    // anahtar yerine girer
    while (j >= 0 && A[j] > anahtar) {
      A[j + 1] = A[j];
      j = j - 1;
    }
    A[j + 1] = anahtar;
  }
}

Araya Ekleyerek Sıralama

Çalışma Süresi ve Analiz Türleri

  • Girdi durumuna bağlı: dizi zaten sıralıysa sıralamak kolaydır.
  • Girdi boyutuna bağlı: az elemanlı dizi kısa sürede sıralanır → T(n).
  • En kötü durum (genellikle): n boyutlu herhangi bir girdi için maksimum süre. Herkes garanti ister.
  • Ortalama durum (bazen): tüm girdiler üzerinden beklenen süre; girdi dağılımı hakkında varsayım gerekir.
  • En iyi durum (yanıltıcı): özel, "hileli" bir girdide geçen süre; tek başına bir şey kanıtlamaz.
en kötüortalamaen iyinkarşılaştırma

Araya ekleme: sıralı girdi → n−1 karşılaştırma; tersten sıralı girdi → n(n−1)/2. Örnek dizimizde: 11 karşılaştırma.

Araya Ekleyerek Sıralama

Dikkat: Durum ve Sınır Farklı Kavramlardır

Durum (case)Hangi girdiye bakıyoruz? En kötü, ortalama, en iyi girdi. Her durumun kendi süre fonksiyonu vardır.
Sınır (bound)Bir fonksiyonu nasıl özetliyoruz? O: üst sınır, Ω: alt sınır, Θ: ikisi birden. Her duruma uygulanabilir.
Araya ekleyerek sıralamaSıkı sınırYorum
En iyi durum (sıralı girdi)Θ(n)n−1 karşılaştırma
En kötü durum (ters sıralı girdi)Θ(n²)n(n−1)/2 karşılaştırma
Tüm girdiler içinO(n²) ve Ω(n)tek bir Θ yazılamaz
Dikkat: "En kötü O(n log n), en iyi Ω(n) ise çalışma süresi Θ(n log n)" çıkarımı yanlıştır. Θ ancak alt ve üst sınır aynı fonksiyon olduğunda yazılır; ör. birleştirerek sıralama her girdide Θ(n log n)'dir.

Araya Ekleyerek Sıralama

Makineden Bağımsız Çalışma Süresi

  • Araya ekleyerek sıralamanın en kötü durumu O(n²): girdi tersten sıralıysa gerçekleşir.
  • Bilgisayarın hızına göre süre değişir; asimptotik analiz büyüme oranına odaklanır, makineye bağlı sabit çarpanlar göz ardı edilir.
  • n → ∞ giderken T(n)'nin büyüme oranına bakılır: yalnızca en önemli (üssü en büyük) terim değerlendirilir.
  • T(n) = 3n² + 2n + 5 = O(n²)
n3n²+2n+53n²oran
103253001,0833
10030.20530.0001,0068
1.0003.002.0053.000.0001,0007

n büyüdükçe düşük dereceli terimlerin payı sıfıra yaklaşır. 3 katsayısı ise makineye bağlıdır: hızlı bilgisayarda 1, yavaşta 10 olabilir → atılır.

Araya Ekleyerek Sıralama

Θ Gösterimi: Tanım ve Uygulama

Θ(g(n)) = { f(n) : tüm n ≥ n₀ değerleri için 0 ≤ c₁ · g(n) ≤ f(n) ≤ c₂ · g(n) şartını sağlayan pozitif c₁, c₂ ve n₀ sabitleri vardır }

Mühendislik kuralı:

  1. T(n) = 3n³ + 90n² − 5n + 6046
  2. Düşük kuvvetli terimleri sil: 3n³
  3. Katsayıları kaldır: T(n) = Θ(n³)
Tanımla doğrulamac₁ = 3: 3n³ ≤ T(n), çünkü 90n² − 5n + 6046 > 0 (her n ≥ 1).
c₂ = 4: T(n) ≤ 4n³ ⇔ 90n² − 5n + 6046 ≤ n³, bu da n ≥ 91 için doğrudur.
⇒ c₁ = 3, c₂ = 4, n₀ = 91 ile T(n) = Θ(n³).

O ve Ω'nın biçimsel tanımları, limit yöntemi ve özellikleri Bölüm 1.2: Karmaşıklık'ta ele alınır.

Böl ve Fethet

Böl ve Fethet (Divide and Conquer)

1. Böl (Divide)Problemi aynı türden, daha küçük alt problemlere ayır.
2. Fethet (Conquer)Alt problemleri özyinelemeli çöz; yeterince küçükse doğrudan çöz.
3. Birleştir (Combine)Alt çözümleri birleştirerek asıl problemin çözümünü elde et.
AlgoritmaBölFethetBirleştirT(n)
Birleştirerek sıralamaortadan ikiye2 yarıyı sıralabirleştirme: Θ(n)2T(n/2) + Θ(n)
İkili aramaortayı kontrol et1 yarıda araönemsiz: Θ(1)T(n/2) + Θ(1)
Üs alma aⁿn'yi ikiye böla⌊n/2⌋ hesaplakare al: Θ(1)T(n/2) + Θ(1)

Böyle özyinelemeli tanımlanan süre fonksiyonlarına yineleme bağıntısı (recurrence) denir. Çözüm yöntemleri (özyineleme ağacı, ana teorem) Bölüm 1.2'de.

Böl ve Fethet

Birleştirerek Sıralama (Merge Sort)

AdımMaliyet
BirleştirSırala A[1 . . n]T(n)
1. n = 1 ise işlem tamam.
2. liste1 = BirleştirSırala A[1 . . ⌈n/2⌉]
3. liste2 = BirleştirSırala A[⌈n/2⌉+1 . . n]
4. İki sıralı listeyi birleştir.

Birleştirerek sıralama (Merge Sort): n elemanlı diziyi sıralamanın süresi T(n) olsun.

AdımMaliyet
BirleştirSırala A[1 . . n]T(n)
1. n = 1 ise işlem tamam.Θ(1)
2. liste1 = BirleştirSırala A[1 . . ⌈n/2⌉]
3. liste2 = BirleştirSırala A[⌈n/2⌉+1 . . n]
4. İki sıralı listeyi birleştir.

n = 1 ise dizi zaten sıralıdır: sabit süre, Θ(1).

AdımMaliyet
BirleştirSırala A[1 . . n]T(n)
1. n = 1 ise işlem tamam.Θ(1)
2. liste1 = BirleştirSırala A[1 . . ⌈n/2⌉]T(n/2)
3. liste2 = BirleştirSırala A[⌈n/2⌉+1 . . n]
4. İki sıralı listeyi birleştir.

Sol yarıyı sıralamak, aynı problemin n/2 boyutlu hâlidir: T(n/2).

AdımMaliyet
BirleştirSırala A[1 . . n]T(n)
1. n = 1 ise işlem tamam.Θ(1)
2. liste1 = BirleştirSırala A[1 . . ⌈n/2⌉]T(n/2)
3. liste2 = BirleştirSırala A[⌈n/2⌉+1 . . n]T(n/2)
4. İki sıralı listeyi birleştir.

Sağ yarı da T(n/2) sürer.

AdımMaliyet
BirleştirSırala A[1 . . n]T(n)
1. n = 1 ise işlem tamam.Θ(1)
2. liste1 = BirleştirSırala A[1 . . ⌈n/2⌉]T(n/2)
3. liste2 = BirleştirSırala A[⌈n/2⌉+1 . . n]T(n/2)
4. İki sıralı listeyi birleştir.Θ(n)
T(n) = Θ(1), n = 1 ise;   T(n) = 2T(n/2) + Θ(n), n > 1 ise.

İki sıralı listeyi birleştirmek her elemanı bir kez yazar: Θ(n). Böylece T(n) = 2T(n/2) + Θ(n).

Böl ve Fethet · Kodu adım adım çalıştır

Birleştirme İşlemi (Merge): Adım Adım

271320A191112BC:01234567

İki sıralı liste: A = 2 7 13 20, B = 1 9 11 12 (en küçükler altta). Yalnızca iki listenin en önündeki (sarı) elemanlar karşılaştırılır.

271320A191112BC:101234567

A[0] = 2 > B[0] = 1 → 1, C'ye yazılır; j ilerler.

271320A191112BC:1021234567

A[0] = 2 ≤ B[1] = 9 → 2, C'ye yazılır; i ilerler.

271320A191112BC:10217234567

A[1] = 7 ≤ B[1] = 9 → 7, C'ye yazılır; i ilerler.

271320A191112BC:102172934567

A[2] = 13 > B[1] = 9 → 9, C'ye yazılır; j ilerler.

271320A191112BC:10217293114567

A[2] = 13 > B[2] = 11 → 11, C'ye yazılır; j ilerler.

271320A191112BC:1021729311412567

A[2] = 13 > B[3] = 12 → 12, C'ye yazılır; j ilerler.

271320A191112BC:102172931141251367

B bitti: A'da kalan 13 doğrudan C'ye kopyalanır (karşılaştırma yok).

271320A191112BC:10217293114125136207

B bitti: A'da kalan 20 doğrudan C'ye kopyalanır (karşılaştırma yok). Sonuç: 1 2 7 9 11 12 13 20. Her eleman bir kez yazıldı → Θ(n).

int i = 0, j = 0, k = 0;
while (i < A.length && j < B.length) {
  if (A[i] <= B[j])
    C[k++] = A[i++];
  else
    C[k++] = B[j++];
}
while (i < A.length)
  C[k++] = A[i++];
while (j < B.length)
  C[k++] = B[j++];

Böl ve Fethet

Birleştirerek Sıralama: Neden Θ(n log n)?

nc·nn/2n/2c·nn/4n/4n/4n/4c·nn/8n/8n/8n/8n/8n/8n/8n/8c·nlog₂ n + 1 düzey × c·n iş ⇒ T(n) = Θ(n log n)
  • n elemanlı listeyi birleştirmek Θ(n) sürer (yukarıdaki örnekte 8 eleman, 8 yazma, 6 karşılaştırma).
  • Her düzeyde alt problemlerin toplam boyutu n'dir → her düzeyin toplam birleştirme işi c·n.
  • Boyut her düzeyde yarıya iner: 1'e inmek için log₂ n bölme gerekir.
  • Araya ekleyerek sıralamanın Θ(n²) en kötü durumuna karşı, birleştirerek sıralama her girdide Θ(n log n)'dir; bedeli O(n) ek bellektir.

Böl ve Fethet · Kodu adım adım çalıştır

İkili Arama: 9'u Bul

3051728394125156altusthedef: 9

Örnek: 9'u bul. Dizi sıralı; aralık tüm dizi: alt = 0, ust = 6.

3051728394125156altustortahedef: 9

orta = (0 + 6) / 2 = 3, tahmin = dizi[3] = 8.

3051728394125156altusthedef: 9

8 < 9 → hedef sağ yarıda: alt = 4. Sol yarı elendi.

3051728394125156altustortahedef: 9

orta = (4 + 6) / 2 = 5, tahmin = dizi[5] = 12.

3051728394125156altusthedef: 9

12 > 9 → hedef sol yarıda: ust = 4. Sağ taraf elendi.

3051728394125156altustortahedef: 9

orta = (4 + 4) / 2 = 4, tahmin = dizi[4] = 9.

3051728394125156altustortahedef: 9

tahmin == aranan → return 4. Yalnızca 3 karşılaştırma (⌊log₂ 7⌋ + 1 = 3).

int ikiliArama(int[] dizi, int aranan) {
  int alt = 0, ust = dizi.length - 1;
  while (alt <= ust) {
    int orta = (alt + ust) / 2;
    int tahmin = dizi[orta];
    if (tahmin == aranan)
      return orta;    // bulundu
    else if (tahmin < aranan)
      alt = orta + 1;
    else
      ust = orta - 1;
  }
  return -1;         // bulunamadı
}

Böl ve Fethet

İkili Arama: Böl ve Fethet Analizi

İkili arama (Binary Search): sıralı listede bir elemanı ararMaliyet
Böl (Divide): orta elemanı kontrol et.Θ(1)
Fethet (Conquer): seçilen alt diziyi özyinelemeli olarak ara.T(n/2)
Birleştir (Combine): önemsiz (trivial); alt dizinin cevabı asıl cevaptır.Θ(1)
T(n) = 1 · T(n/2) + Θ(1)alt problem sayısıalt problem büyüklüğübölme + birleştirme

Açılım: T(n) = T(n/2) + c = T(n/4) + 2c = … = T(1) + c · log₂ n ⇒ T(n) = Θ(log n)

Böl ve Fethet

Bir Sayının Üssünü Alma: aⁿ

Problem: aⁿ'i hesapla (n ∈ ℕ). Doğal algoritma: aⁿ = a · a · … · a → Θ(n) çarpma.

Böl ve fethet:

aⁿ = an/2 · an/2  (n çift ise)
aⁿ = a(n−1)/2 · a(n−1)/2 · a  (n tek ise)
long us(long a, int n) {
  if (n == 0) return 1;
  long yarim = us(a, n / 2);        // a^(n/2), tek kez!
  if (n % 2 == 0)
    return yarim * yarim;           // n çift
  else
    return a * yarim * yarim;       // n tek
}
ndoğalböl-fethet
10106
626211
1.0001.00016
1.000.0001.000.00027

çarpma sayıları (yukarıdaki kodla). Örn. 2¹⁰: n = 10 → 5 → 2 → 1 → 0.

T(n) = T(n/2) + Θ(1)
⇒ T(n) = Θ(lg n)

Euclid Algoritması

Euclid Algoritması (EBOB)

  • En büyük ortak böleni (EBOB, gcd) bulur.
  • Bilinen en eski algoritmalardan biridir (Öklid, MÖ ~300); en basit EBOB yöntemi.
  • Temel fikir: ebob(a, b) = ebob(b, a mod b), ebob(a, 0) = a.
  1. Adım 1: büyük sayıyı küçüğe böl, kalanı al.
  2. Adım 2: kalan sıfır olana kadar (bölen, kalan) çiftiyle tekrarla.
  3. Adım 3: kalan sıfır olduğunda son bölen EBOB'dur.
int ebob(int a, int b) {
  if (b == 0)
    return a;
  return ebob(b, a % b);
}
Neden doğru?a = q·b + r ise a ile b'yi bölen her sayı r = a − q·b'yi de böler; b ile r'yi bölen her sayı a'yı da böler. Ortak bölenler aynıdır.

Euclid Algoritması · Kodu adım adım çalıştır

ebob(1599, 650): Adım Adım

6506502991599 × 650 dikdörtgen

1599 = 2 · 650 + 299. 1599×650 dikdörtgenden 2 kare kesilir, kalan şerit 650×299 → ebob(650, 299).

29929952650 × 299 dikdörtgen

650 = 2 · 299 + 52. 650×299 dikdörtgenden 2 kare kesilir, kalan şerit 299×52 → ebob(299, 52).

525252525239299 × 52 dikdörtgen

299 = 5 · 52 + 39. 299×52 dikdörtgenden 5 kare kesilir, kalan şerit 52×39 → ebob(52, 39).

391352 × 39 dikdörtgen

52 = 1 · 39 + 13. 52×39 dikdörtgenden 1 kare kesilir, kalan şerit 39×13 → ebob(39, 13).

13131339 × 13 dikdörtgen

39 = 3 · 13 + 0. 39×13 dikdörtgenden 3 kare kesilir, kalan şerit 13×0 → ebob(13, 0).

ebob(13, 0) = 13

b == 0 → return 13. 13, 1599 ile 650'yi tam bölen en büyük sayıdır.

6506502991599 × 650 dikdörtgen

Dönüş değeri 13 tüm çağrılardan aynen geri döner: ebob(1599, 650) = 13. 5 bölme yetti. 13 × 13'lük kareler 1599 × 650'yi tam döşer.

int ebob(int a, int b) {
  if (b == 0)
    return a;
  return ebob(b, a % b);
}

Euclid Algoritması

Euclid Algoritması: Neden Hızlı?

  • Verimli ve hızlı çalışır: her iki adımda büyük sayı en az yarıya iner (a mod b < a/2).
  • Bu yüzden adım sayısı en fazla ≈ 2 log₂ min(a, b): O(log min(a, b)).
  • En kötü senaryo ardışık Fibonacci sayılarıyla oluşur: her bölümde q = 1 çıkar, sayılar en yavaş küçülür (Lamé teoremi).
  • Karşılaştırma: 1'den min(a, b)'ye kadar tüm bölenleri denemek O(min(a, b)) sürer.
En kötü örnek: ebob(55, 34)55 = 1 · 34 + 21
34 = 1 · 21 + 13
21 = 1 · 13 + 8
13 = 1 · 8 + 5
8 = 1 · 5 + 3
5 = 1 · 3 + 2
3 = 1 · 2 + 1
2 = 2 · 1 + 0

8 bölme, EBOB = 1. Karşılaştırın: ebob(1599, 650) yalnızca 5 bölme.

Özet

Özet

KonuHatırlanacaklar
Algoritmagirdi → açık, sonlu, etkin adımlar → çıktı; dilden bağımsızdır
AnalizT(n): girdi boyutuna göre temel işlem sayısı; zaman ve bellek
Durumlaren kötü (garanti), ortalama (beklenen), en iyi (yanıltıcı)
GösterimlerO üst, Ω alt, Θ sıkı sınır; sabitler ve düşük terimler atılır
Sınıflar1 < log n < √n < n < n log n < n² < n³ < 2ⁿ < n!
Araya eklemeen iyi Θ(n), en kötü Θ(n²), yerinde, O(1) ek bellek
Böl ve fethetbirleştirerek sıralama 2T(n/2) + Θ(n) = Θ(n log n); ikili arama ve üs alma T(n/2) + Θ(1) = Θ(log n)
Euclidebob(a, b) = ebob(b, a mod b); O(log min(a, b)); en kötü: ardışık Fibonacci

Özet

Etkileşimli Simülatörler

Algoritma Karmaşıklığı AnaliziO(log n), O(n), O(n log n), O(n²) ve O(n³) örnek JavaScript fonksiyonlarından birini seçin ya da kendi fonksiyonunuzu yazın; beş farklı girdi boyutunda tarayıcıda çalıştırıp ölçülen süreleri grafikte karşılaştırın.
Bu bölümde: Büyüme Hesaplayıcı"Deneyin: Büyüme" slaytında bir n değeri girin; 1'den n!'e kadar her fonksiyonun işlem sayısını ve saniyede 10⁹ işlem yapan bir bilgisayardaki süresini görün.

Özet

Sık Yapılan Hatalar

O = en kötü, Ω = en iyi sanmakO, Ω, Θ sınır türleridir; her durum (en kötü, en iyi) için ayrı ayrı yazılabilir.
Yanlış Θ çıkarımıEn kötü O(n²), en iyi Ω(n) ise tüm girdiler için tek bir Θ yoktur. Θ için iki sınır aynı olmalı.
Süreyi saniyeyle ölçmekSaniye makineye bağlıdır; analizde n'ye bağlı işlem sayısı ve büyüme hızı kullanılır.
Ezberlemeyi unutmakSaf özyinelemeli Fibonacci O(2ⁿ)'dir; aynı alt problemi saklamak onu O(n)'e indirir.
Ortalama = garanti sanmakHızlı sıralama ortalamada O(n log n), ama sıralı girdide ilk eleman pivotla O(n²)'dir.
Sıralanmamış diziye ikili aramaİkili arama yalnızca sıralı dizide doğrudur; aksi hâlde var olan eleman "yok" bulunabilir.

Özet

Örnek Problemler

  1. Araya ekleyerek sıralama [5, 4, 3, 2, 1] ve [1, 2, 3, 4, 5] dizilerinde kaç karşılaştırma ve kaç kaydırma yapar?
  2. T(n) = 5n² + 100n log₂ n + 7 için Θ sınıfını yazın. n = 1000'de hangi terim baskındır?
  3. [2, 4, 7, 10, 13, 18, 21, 25, 30] dizisinde ikili arama ile 21 ve 5'i arayın; incelenen orta elemanları yazın.
  4. ebob(252, 105)'i Euclid algoritmasıyla bulun.
  5. 2¹³ yukarıdaki us fonksiyonuyla hesaplanırken hangi üsler için çağrı yapılır, kaç çarpma gerekir?
Cevapları göster
  1. [5,4,3,2,1]: 10 karşılaştırma, 10 kaydırma (en kötü, n(n−1)/2). [1,2,3,4,5]: 4 karşılaştırma, 0 kaydırma (en iyi, n−1).
  2. Θ(n²). n = 1000: 5n² = 5.000.000, 100n log₂ n ≈ 996.578 → 5n² baskın.
  3. 21: orta elemanlar 13, 21 → indis 6. 5: 13, 4, 7 → bulunamadı (−1).
  4. 252 = 2·105 + 42; 105 = 2·42 + 21; 42 = 2·21 + 0 → EBOB = 21.
  5. n = 13 → 6 → 3 → 1 → 0; çarpma: 7 (tek üslerde 2, çiftte 1). Doğal yöntem 13 çarpma.

Özet

Alıştırmalar

  1. Bir dizide verilen bir sayının kaç kez geçtiğini bulan algoritmayı yazın; zaman ve bellek karmaşıklığını verin.
  2. İç içe döngüler: for i in 0..n-1: for j in i..n-1: işlem kaç kez çalışır? Sınıfı nedir?
  3. Araya ekleyerek sıralamayı azalan sırada sıralayacak şekilde değiştirin. Hangi satır değişir?
  4. Euclid algoritmasını döngüyle (özyinelemesiz) yazın.
  5. Saniyede 10⁹ işlemle 1 saniyede çözülebilecek en büyük n: f(n) = n² ve f(n) = 2ⁿ için bulun.
  6. while (n > 1) n = n / 2; döngüsü kaç kez döner?
Cevaplar / ipuçları
  1. Tek geçiş, sayaç: zaman Θ(n), ek bellek O(1).
  2. n + (n−1) + … + 1 = n(n+1)/2 → Θ(n²).
  3. Yalnızca A[j] > anahtar koşulu A[j] < anahtar olur.
  4. while (b != 0) { int r = a % b; a = b; b = r; } return a;
  5. n² ≤ 10⁹ → n ≈ 31.622; 2ⁿ ≤ 10⁹ → n = 29.
  6. ⌊log₂ n⌋ kez → Θ(log n).

Özet

Kaynaklar

  • Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, MIT Press, 2022 (Bölüm 1–3).
  • Sedgewick ve Wayne, Algorithms, 4. baskı, Addison-Wesley, 2011 (Bölüm 1.4: Analysis of Algorithms).
  • D. E. Knuth, The Art of Computer Programming, Vol. 1: Fundamental Algorithms, 3. baskı, 1997 (algoritmanın özellikleri; Euclid).
  • J. Kleinberg ve É. Tardos, Algorithm Design, Pearson, 2005 (Bölüm 2: Basics of Algorithm Analysis).

Son

Bölüm 1: Giriş
Sonraki bölüm: Bölüm 1.2: Algoritma Karmaşıklığı
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.