Bölüm 4.1: Algoritmalar

Bilgisayar ve Programlamaya Giriş
ProblemAlgoritmaİzlemeAramaSıralama
Sercan KÜLCÜ · Giresun Üniversitesi

Giriş

Öğrenme Çıktıları

Tanımlama

Girdi, çıktı ve kısıtları belirlemek.

Tasarım

Çözümü açık ve sonlu adımlara ayırmak.

Doğrulama

Algoritmayı örneklerle izlemek ve test etmek.

Karşılaştırma

Arama ve sıralama yaklaşımlarını değerlendirmek.

Problem Çözme

Önce Algoritma, Sonra Kod

  • Kod, çözüm fikrinin belirli bir dildeki uygulamasıdır.
  • Algoritma kurulmadan yazılan kod gereksiz denemelere ve gizli hatalara yol açabilir.
  • Doğru sıra: problemi anla, örnek çöz, yöntemi yaz, sonra kodla.
Problemi anlaen büyük sayı?Örnek çöz3, 8, 5 → 8Yöntemi yazen büyük = ilkdaha büyüğü görünce güncelleKodlaJava, Python, C…Turuncu adım (algoritma) dilden bağımsızdır; aynı yöntem her dilde kodlanabilir.

Problem Çözme

Problem Tanımı

Amaç

Hangi sorun çözülecek?

Girdi

Programa hangi bilgiler verilecek?

Çıktı

Hangi sonuç üretilecek?

Kısıt

Değerlerin sınırı ve geçerlilik koşulu nedir?

Örnek

Beklenen sonuç hangi küçük örnekle doğrulanabilir?

Hata durumu

Geçersiz veya eksik girdide ne yapılacak?

Girdi: ntam sayıAlgoritmafaktöriyel hesabıÇıktı: n!5 → 120Kısıt: 0 ≤ n ≤ 20 (long tipine sığar) · n < 0 ise hata

Algoritma

İyi Algoritmanın Özellikleri

Algoritma, belirli bir problemi çözmek için tanımlanmış sonlu adımlar dizisidir.

  • Sıfır veya daha fazla girdi alır, en az bir çıktı üretir.
  • Adımlar açık, sıralı ve uygulanabilir olmalıdır.
  • Sonlu sayıda adım sonra durmalıdır.
  • Geçerli girdiler için doğru sonucu üretmelidir.
  • Kaynak kullanımı girdi boyutu büyüdüğünde kabul edilebilir olmalıdır.
i = 1; i ≠ 10 iken i = i + 210 hiç olmaz: durmaz ✗01234567891011121314…i = 1; i ≤ 10 iken i = i + 2i = 11 olunca durur ✓01234567891011121314

Algoritma

Algoritma Tasarlama Döngüsü

1. Örneği çöz2. Genel kuralı bul3. Sözde kod yaz4. Elle izle5. Düzelt
  • Elle izlemede hata çıkarsa düzeltilir ve döngü yeniden döner; hata kalmayınca kodlamaya geçilir.
  • Birden fazla çözüm varsa doğruluk, okunabilirlik ve verimlilik karşılaştırılır.

Algoritma

Sözde Kod

Sözde kod, algoritmanın mantığını belirli bir programlama diline bağlı kalmadan açıklar.

BAŞLA
  A değerini oku
  B değerini oku
  TOPLAM = A + B
  TOPLAM değerini yaz
BİTİR
BAŞLAA’yı okuB’yi okuTOPLAM = A + BTOPLAM’ı yazBİTİR
  • Doğal dile yakın, kısa ve tutarlı ifadeler kullanılır.
  • Girinti, koşul ve döngülerin kapsamını gösterir.
  • Amaç söz dizimi değil, algoritmayı anlaşılır hale getirmektir.

Örnekler

Örnek: İki Sayıyı Sırala

oku a, b
eğer a > b ise
    gecici = a
    a = b
    b = gecici
yaz a, b
  • Eşit değerlerde değişim gerekmez.
  • Takas üç atamayla yapılır.
  • Çıktı için a ≤ b koşulu sağlanmalıdır.
a7 → 3gecici— → 7b3 → 7① gecici = a③ b = gecici② a = b
Neden gecici değişkeni? Doğrudan a = b; b = a yazılırsa ilk atama a'nın eski değerini siler: a = 7, b = 3 için sonuç 3 3 olur.

Örnekler · Adım adım izleme

İki Sayıyı Sırala Adım Adım (a = 7, b = 3)

a7b3gecici—

Girdiler okunur: a = 7, b = 3. Hedef: küçük olan önce yazılsın.

a7b3gecici—

Koşul: 7 > 3 → doğru → takas bloğuna girilir.

a7b3gecici7kopyala

gecici = a = 7: a'nın değeri kaybolmasın diye önce yedeklenir.

a3b3gecici7kopyala

a = b = 3. Eski 7 artık yalnızca gecici'de duruyor.

a3b7gecici7kopyala

b = gecici = 7. Üç atamayla değerler yer değiştirdi.

a3b7gecici7

Çıktı 3 7: a ≤ b sağlandı. (a = 2, b = 9 girilseydi koşul yanlış olur, 3–5. satırlar atlanırdı.)

oku a, b
eğer a > b ise
    gecici = a
    a = b
    b = gecici
yaz a, b

Örnekler

Örnek: Faktöriyel

oku n
eğer n < 0 ise "hata" yaz ve dur
sonuc = 1
i = 2
i ≤ n iken
    sonuc = sonuc × i
    i = i + 1
yaz sonuc
  • 0! ve 1! değeri 1'dir: döngü hiç dönmez, sonuc = 1 kalır.
  • Döngü değişmezi: her tur başında sonuc = (i − 1)!
  • Negatif girdide hata verilip durulur.
n = 5: her tur başında sonuc = (i − 1)!1i = 2× 22i = 3× 36i = 4× 424i = 5× 5120i = 6 → dur

Örnekler · Adım adım izleme

Faktöriyel Adım Adım (n = 5)

n5sonuc—i—çarpım:1×2×3×4×5

n = 5 okunur. Beklenen: 5! = 1×2×3×4×5.

n5sonuc—i—çarpım:1×2×3×4×5

Koşul: 5 < 0 → yanlış; hata yok, devam.

n5sonuc1i—çarpım:1×2×3×4×5

Çarpım için başlangıç değeri 1 (0 olsaydı her şey 0 çıkardı).

n5sonuc1i2çarpım:1×2×3×4×5

i = 2: 1 ile çarpmak değeri değiştirmez, 2'den başlanır.

n5sonuc1i2çarpım:1×2×3×4×5

Koşul: 2 ≤ 5 → doğru.

n5sonuc2i2çarpım:1×2×3×4×5

sonuc = 1 × 2 = 2 (= 2!).

n5sonuc2i3çarpım:1×2×3×4×5

i = 3.

n5sonuc2i3çarpım:1×2×3×4×5

Koşul: 3 ≤ 5 → doğru.

n5sonuc6i3çarpım:1×2×3×4×5

sonuc = 2 × 3 = 6 (= 3!).

n5sonuc6i4çarpım:1×2×3×4×5

i = 4.

n5sonuc6i4çarpım:1×2×3×4×5

Koşul: 4 ≤ 5 → doğru.

n5sonuc24i4çarpım:1×2×3×4×5

sonuc = 6 × 4 = 24 (= 4!).

n5sonuc24i5çarpım:1×2×3×4×5

i = 5.

n5sonuc24i5çarpım:1×2×3×4×5

Koşul: 5 ≤ 5 → doğru.

n5sonuc120i5çarpım:1×2×3×4×5

sonuc = 24 × 5 = 120 (= 5!).

n5sonuc120i6çarpım:1×2×3×4×5

i = 6.

n5sonuc120i6çarpım:1×2×3×4×5

Koşul: 6 ≤ 5 → yanlış → döngü biter.

n5sonuc120i6çarpım:1×2×3×4×5

120 yazılır. Döngü n − 1 = 4 kez döndü.

oku n
eğer n < 0 ise "hata" yaz ve dur
sonuc = 1
i = 2
i ≤ n iken
    sonuc = sonuc × i
    i = i + 1
yaz sonuc

Örnekler

Örnek: Fibonacci

oku n
a = 0, b = 1
0'dan n-1'e kadar tekrarla
    yaz a
    sonraki = a + b
    a = b
    b = sonraki
  • İki önceki değer korunur: a ve b her turda bir sağa kayan pencere gibidir.
  • Geçici değişken güncelleme sırasında bilgi kaybını önler.
011235813absonraki2 + 3 = 5Tur 3: a (2) yazılır, sonraki = a + b; sonra a = 3, b = 5 olur ve pencere bir sağa kayar.

Örnekler · Adım adım izleme

Fibonacci Adım Adım (n = 8, tur 0–2)

çıktı:a—b—sonraki—

n = 8: ilk 8 Fibonacci sayısı yazılacak.

çıktı:a0b1sonraki—

Dizinin ilk iki terimi: a = 0, b = 1.

çıktı:0a0b1sonraki—

Tur 0 (0…7): a = 0 yazılır.

çıktı:0a0b1sonraki1

sonraki = 0 + 1 = 1.

çıktı:0a1b1sonraki1

a = b = 1: pencere bir kayar.

çıktı:0a1b1sonraki1

b = sonraki = 1. Sıra önemli: önce a = b yapılmasaydı eski b kaybolurdu.

çıktı:01a1b1sonraki1

Tur 1 (0…7): a = 1 yazılır.

çıktı:01a1b1sonraki2

sonraki = 1 + 1 = 2.

çıktı:01a1b1sonraki2

a = b = 1: pencere bir kayar.

çıktı:01a1b2sonraki2

b = sonraki = 2.

çıktı:011a1b2sonraki2

Tur 2 (0…7): a = 1 yazılır.

çıktı:011a1b2sonraki3

sonraki = 1 + 2 = 3.

çıktı:011a2b2sonraki3

a = b = 2: pencere bir kayar.

çıktı:011a2b3sonraki3

b = sonraki = 3.

oku n
a = 0, b = 1
0'dan n-1'e kadar tekrarla
    yaz a
    sonraki = a + b
    a = b
    b = sonraki

Örnekler · Adım adım izleme

Fibonacci Adım Adım (devam: tur 3–5)

çıktı:0112a2b3sonraki3

Tur 3 (0…7): a = 2 yazılır.

çıktı:0112a2b3sonraki5

sonraki = 2 + 3 = 5.

çıktı:0112a3b3sonraki5

a = b = 3: pencere bir kayar.

çıktı:0112a3b5sonraki5

b = sonraki = 5.

çıktı:01123a3b5sonraki5

Tur 4 (0…7): a = 3 yazılır.

çıktı:01123a3b5sonraki8

sonraki = 3 + 5 = 8.

çıktı:01123a5b5sonraki8

a = b = 5: pencere bir kayar.

çıktı:01123a5b8sonraki8

b = sonraki = 8.

çıktı:011235a5b8sonraki8

Tur 5 (0…7): a = 5 yazılır.

çıktı:011235a5b8sonraki13

sonraki = 5 + 8 = 13.

çıktı:011235a8b8sonraki13

a = b = 8: pencere bir kayar.

çıktı:011235a8b13sonraki13

b = sonraki = 13.

oku n
a = 0, b = 1
0'dan n-1'e kadar tekrarla
    yaz a
    sonraki = a + b
    a = b
    b = sonraki

Örnekler · Adım adım izleme

Fibonacci Adım Adım (devam: tur 6–7)

çıktı:0112358a8b13sonraki13

Tur 6 (0…7): a = 8 yazılır.

çıktı:0112358a8b13sonraki21

sonraki = 8 + 13 = 21.

çıktı:0112358a13b13sonraki21

a = b = 13: pencere bir kayar.

çıktı:0112358a13b21sonraki21

b = sonraki = 21.

çıktı:011235813a13b21sonraki21

Tur 7 (0…7): a = 13 yazılır.

çıktı:011235813a13b21sonraki34

sonraki = 13 + 21 = 34.

çıktı:011235813a21b21sonraki34

a = b = 21: pencere bir kayar.

çıktı:011235813a21b34sonraki34

b = sonraki = 34.

çıktı:011235813a21b34sonraki34

8 tur tamamlandı, döngü biter. Çıktı: 0 1 1 2 3 5 8 13. Son yazılan terim 13.

oku n
a = 0, b = 1
0'dan n-1'e kadar tekrarla
    yaz a
    sonraki = a + b
    a = b
    b = sonraki

Örnekler

Örnek: Palindrom

metni oku
metni kurala göre temizle
sol = 0, sag = uzunluk - 1
sol < sag iken
    karakterler farklıysa yanlış döndür
    sol = sol + 1, sag = sag - 1
doğru döndür
  • Karşılaştırma iki uçtan merkeze ilerler.
  • Büyük-küçük harf ve boşluk kuralı önceden belirlenmelidir (ör. "Kayak" → "kayak").
  • En fazla uzunluk / 2 karşılaştırma yapılır.
0k1a2y3a4ksol = 0 →← sag = 4Dıştan içe: k = k, a = a; ortadaki y ile karşılaştırma gerekmez → ⌊5 / 2⌋ = 2 karşılaştırma

Örnekler · Adım adım izleme

Palindrom Adım Adım ("Kayak")

0K1a2y3a4k

Metin okunur: "Kayak". İlk harf büyük.

0k1a2y3a4k

Kural: küçük harfe çevir, boşlukları at → "kayak". Yoksa K ≠ k sanılırdı.

0k1a2y3a4k▲ sol▲ sag

İki uç: sol = 0, sag = 4.

0k1a2y3a4k▲ sol▲ sag

Koşul: 0 < 4 → doğru.

0k1a2y3a4k▲ sol▲ sag

metin[0] = 'k', metin[4] = 'k' → aynı, devam.

0k1a2y3a4k▲ sol▲ sag

İçe doğru bir adım: sol = 1, sag = 3.

0k1a2y3a4k▲ sol▲ sag

Koşul: 1 < 3 → doğru.

0k1a2y3a4k▲ sol▲ sag

metin[1] = 'a', metin[3] = 'a' → aynı, devam.

0k1a2y3a4k▲ solsag

İçe doğru bir adım: sol = 2, sag = 2.

0k1a2y3a4k▲ solsag

Koşul: 2 < 2 → yanlış: ortaya gelindi, döngü biter.

0k1a2y3a4k▲ solsag

Farklı çift bulunmadı → doğru: "Kayak" bir palindromdur. 5 harf için yalnızca 2 karşılaştırma yapıldı.

metni oku
metni kurala göre temizle
sol = 0, sag = uzunluk - 1
sol < sag iken
    karakterler farklıysa yanlış döndür
    sol = sol + 1, sag = sag - 1
doğru döndür

Örnekler

Örnek: Asal Sayı

oku n
eğer n < 2 ise "asal değil" yaz ve dur
i = 2
i × i ≤ n iken
    eğer n % i == 0 ise "asal değil" yaz ve dur
    i = i + 1
"asal" yaz
  • Bir bölen bulununca arama durur.
  • Karekök sınırı: n = a × b ise a ve b'nin ikisi birden √n'den büyük olamaz; küçük bölen varsa i × i ≤ n aralığında bulunur.
  • % işlemi bölümden kalanı verir.
12346 = √36912183636 = 1×36 = 2×18 = 3×12 = 4×9 = 6×6: her çiftin küçüğü ≤ √36 → i = 2…6 denemek yeter

Örnekler · Adım adım izleme

Asal Sayı Adım Adım (n = 29)

n = 29i:234567√29 ≈ 5,39

n = 29 okunur.

n = 29i:234567√29 ≈ 5,39

29 < 2 → yanlış; 0 ve 1 değil, devam.

n = 29i:234567√29 ≈ 5,39

i = 2: ilk aday bölen.

n = 29i:234567√29 ≈ 5,39

Koşul: 2×2 = 4 ≤ 29 → doğru.

n = 29i:229%2=134567√29 ≈ 5,39

29 % 2 = 1 → sıfır değil, i bölen değil.

n = 29i:229%2=134567√29 ≈ 5,39

i = 3.

n = 29i:229%2=134567√29 ≈ 5,39

Koşul: 3×3 = 9 ≤ 29 → doğru.

n = 29i:229%2=1329%3=24567√29 ≈ 5,39

29 % 3 = 2 → sıfır değil, i bölen değil.

n = 29i:229%2=1329%3=24567√29 ≈ 5,39

i = 4.

n = 29i:229%2=1329%3=24567√29 ≈ 5,39

Koşul: 4×4 = 16 ≤ 29 → doğru.

n = 29i:229%2=1329%3=2429%4=1567√29 ≈ 5,39

29 % 4 = 1 → sıfır değil, i bölen değil.

n = 29i:229%2=1329%3=2429%4=1567√29 ≈ 5,39

i = 5.

n = 29i:229%2=1329%3=2429%4=1567√29 ≈ 5,39

Koşul: 5×5 = 25 ≤ 29 → doğru.

n = 29i:229%2=1329%3=2429%4=1529%5=467√29 ≈ 5,39

29 % 5 = 4 → sıfır değil, i bölen değil.

n = 29i:229%2=1329%3=2429%4=1529%5=467√29 ≈ 5,39

i = 6.

n = 29i:229%2=1329%3=2429%4=1529%5=467√29 ≈ 5,39

Koşul: 6×6 = 36 ≤ 29 → yanlış: i artık √29'yi geçti, aramaya gerek yok.

n = 29i:229%2=1329%3=2429%4=1529%5=467√29 ≈ 5,392, 3, 4, 5 denendi; 6 ve sonrası gereksiz

Bölen bulunmadı → asal. Yalnızca 4 bölen denendi (2…28 yerine). n = 21 olsaydı i = 3'te 21 % 3 = 0 → asal değil.

oku n
eğer n < 2 ise "asal değil" yaz ve dur
i = 2
i × i ≤ n iken
    eğer n % i == 0 ise "asal değil" yaz ve dur
    i = i + 1
"asal" yaz

Doğrulama

Algoritmayı İzleme

  • Değişkenlerin her adımdaki değeri bir izleme tablosuna yazılır.
  • Normal, sınır ve geçersiz girdiler ayrı ayrı denenir.
  • Beklenen ve gerçek sonuç ayrıldığında ilk farklı adım bulunur.

Faktöriyel, n = 4 için izleme tablosu (i: tur başı değeri, sonuc: tur sonu değeri):

Anisonuci ≤ n
başlangıç21—
tur 122doğru
tur 236doğru
tur 3424doğru
çıkış5245 ≤ 4 yanlış
Tek bir başarılı test, algoritmanın her girdi için doğru olduğunu kanıtlamaz.

Doğrulama

Test Durumları: Faktöriyel Örneği

TürAmaçGirdiBeklenen
NormalYaygın kullanımı doğrulamakn = 5120
SınırAlt sınırı denemekn = 01 (döngü hiç dönmez)
GeçersizHata davranışını görmekn = -3"hata"
BüyükTaşmayı görmekn = 2121! = 51.090.942.171.709.440.000 → 64 bitlik tam sayıya sığmaz
-3052021-3 → "hata"0 → 15 → 12020! sığar21! taşargeçersiz (n < 0)geçerli: 0 ≤ n ≤ 20long taşar
64 bitlik tam sayı (Java long) en çok 9.223.372.036.854.775.807 tutar; 20! = 2.432.902.008.176.640.000 sığar. 21! sığmaz. Bu yüzden kısıt 0 ≤ n ≤ 20 olarak yazılır.

Analiz

Aynı Problem, İki Algoritma: 1 + 2 + … + n

toplam = 0
i = 1
while i <= n
    toplam = toplam + i
    i = i + 1

A: döngü, n tur

toplam = n * (n + 1) / 2

B: Gauss formülü, tek adım

Toplama işlemi sayısın = 10döngü: 10 toplamaformül: 1 toplama + 1 çarpma + 1 bölme · sonuç 55n = 100döngü: 100 toplamaformül: 1 toplama + 1 çarpma + 1 bölme · sonuç 5.050n = 1.000döngü: 1.000 toplamaformül: 1 toplama + 1 çarpma + 1 bölme · sonuç 500.500
İkisi de doğru; ama n büyüdükçe A’nın işi artar, B’ninki sabit kalır: doğruluk kadar verimlilik de önemlidir.

Analiz

Doğruluk ve Verimlilik

  • Doğruluk algoritmanın beklenen sonucu üretmesidir.
  • Zaman karmaşıklığı işlem sayısının girdi boyutuyla değişimini inceler; büyük O gösterimiyle yazılır: O(n), O(log n), O(n²).
  • Alan karmaşıklığı kullanılan ek bellek miktarını değerlendirir.
  • En hızlı görünen yöntem küçük veride her zaman en anlaşılır yöntem olmayabilir.
n⌊log₂ n⌋ + 1 (ikili arama)n (doğrusal arama)n² (basit sıralama)
10410100
100710010.000
1.000101.0001.000.000
1.000.000201.000.0001.000.000.000.000

Arama

Doğrusal Arama

int ara(int[] dizi, int hedef) {
    for (int i = 0; i < dizi.length; i++) {
        if (dizi[i] == hedef) return i;
    }
    return -1;
}
  • Öğeler baştan sona karşılaştırılır; verinin sıralı olması gerekmez.
  • İlk eşleşmede sonlanır, bulunamazsa -1 döndürür.
  • En kötü durumda n öğe incelenir: O(n).

Kod Java ile yazıldı.

Arama · Kodu adım adım çalıştır

Doğrusal Arama Adım Adım (hedef = 5)

0713293541

ara(dizi, 5) çağrıldı. Dizi sıralı değil; baştan tek tek bakılacak.

0713293541▲ i

i = 0: 0 < 5 → doğru.

0713293541▲ i

dizi[0] = 7 == 5 → yanlış.

0713293541▲ i

i = 1: 1 < 5 → doğru.

0713293541▲ i

dizi[1] = 3 == 5 → yanlış.

0713293541▲ i

i = 2: 2 < 5 → doğru.

0713293541▲ i

dizi[2] = 9 == 5 → yanlış.

0713293541▲ i

i = 3: 3 < 5 → doğru.

0713293541▲ i

dizi[3] = 5 == 5 → doğru → return 3. 4 karşılaştırma yapıldı; hedef 4 olsaydı 5 karşılaştırmadan sonra -1 dönerdi.

int ara(int[] dizi, int hedef) {
    for (int i = 0; i < dizi.length; i++) {
        if (dizi[i] == hedef) return i;
    }
    return -1;
}

Arama

İkili Arama

int ikiliAra(int[] dizi, int hedef) {
    int sol = 0, sag = dizi.length - 1;
    while (sol <= sag) {
        int orta = sol + (sag - sol) / 2;
        if (dizi[orta] == hedef) return orta;
        if (dizi[orta] < hedef) sol = orta + 1;
        else sag = orta - 1;
    }
    return -1;
}
  • Yalnızca sıralı veri üzerinde çalışır; her adımda aralığı yarıya indirir.
  • En kötü durumda ⌊log₂ n⌋ + 1 tur: O(log n).
  • sol + (sag - sol) / 2, (sol + sag) / 2 ile aynı sonucu verir ama çok büyük indislerde taşmaz.
  • Tek arama için önce sıralama yapmak toplam maliyeti artırabilir.

Arama · Kodu adım adım çalıştır

İkili Arama Adım Adım (hedef = 34)

0318212317421525630734840▲ sol▲ sag

Arama aralığı tüm dizi: sol = 0, sag = 8.

0318212317421525630734840▲ sol▲ sag

0 ≤ 8 → doğru: aralık boş değil, 1. tur.

0318212317421525630734840▲ sol▲ sag▲ orta

orta = 0 + (8 − 0) / 2 = 4, dizi[4] = 21.

0318212317421525630734840▲ sol▲ sag▲ orta

21 == 34 → yanlış.

0318212317421525630734840▲ sol▲ sag

21 < 34 → hedef sağ yarıda: sol = 5. Sol yarı elendi.

0318212317421525630734840▲ sol▲ sag

5 ≤ 8 → doğru: aralık boş değil, 2. tur.

0318212317421525630734840▲ sol▲ sag▲ orta

orta = 5 + (8 − 5) / 2 = 6, dizi[6] = 30.

0318212317421525630734840▲ sol▲ sag▲ orta

30 == 34 → yanlış.

0318212317421525630734840▲ sol▲ sag

30 < 34 → hedef sağ yarıda: sol = 7. Sol yarı elendi.

0318212317421525630734840▲ sol▲ sag

7 ≤ 8 → doğru: aralık boş değil, 3. tur.

0318212317421525630734840▲ sol orta▲ sag

orta = 7 + (8 − 7) / 2 = 7, dizi[7] = 34.

0318212317421525630734840▲ sol orta▲ sag

34 == 34 → return 7. 3 turda bulundu; doğrusal arama 8 karşılaştırma yapardı.

int ikiliAra(int[] dizi, int hedef) {
    int sol = 0, sag = dizi.length - 1;
    while (sol <= sag) {
        int orta = sol + (sag - sol) / 2;
        if (dizi[orta] == hedef) return orta;
        if (dizi[orta] < hedef) sol = orta + 1;
        else sag = orta - 1;
    }
    return -1;
}

Arama · Kodu adım adım çalıştır

İkili Arama: Hedef Bulunamadı (hedef = 19)

0318212317421525630740▲ sol▲ sag

Arama aralığı tüm dizi: sol = 0, sag = 7. Aranan 19 dizide yok (17 ile 21 arasında olurdu).

0318212317421525630740▲ sol▲ sag

0 ≤ 7 → doğru: aralık boş değil, 1. tur.

0318212317421525630740▲ sol▲ orta▲ sag

orta = 0 + (7 − 0) / 2 = 3, dizi[3] = 17.

0318212317421525630740▲ sol▲ orta▲ sag

17 == 19 → yanlış.

0318212317421525630740▲ sol▲ sag

17 < 19 → doğru: hedef sağ yarıda olabilir, sol = 4. Sol yarı elendi.

0318212317421525630740▲ sol▲ sag

4 ≤ 7 → doğru: aralık boş değil, 2. tur.

0318212317421525630740▲ sol▲ orta▲ sag

orta = 4 + (7 − 4) / 2 = 5, dizi[5] = 25.

0318212317421525630740▲ sol▲ orta▲ sag

25 == 19 → yanlış.

0318212317421525630740▲ sol sag

25 < 19 → yanlış, else: hedef sol yarıda olabilir, sag = 4. Sağ yarı elendi.

0318212317421525630740▲ sol sag

4 ≤ 4 → doğru: aralık boş değil, 3. tur.

0318212317421525630740▲ sol orta sag

orta = 4 + (4 − 4) / 2 = 4, dizi[4] = 21.

0318212317421525630740▲ sol orta sag

21 == 19 → yanlış.

0318212317421525630740▲ sag▲ sol

21 < 19 → yanlış, else: hedef sol yarıda olabilir, sag = 3. Sağ yarı elendi.

0318212317421525630740▲ sag▲ sol

4 ≤ 3 → yanlış: sol, sag’ı geçti; aralık boş, döngü biter.

0318212317421525630740▲ sag▲ sol

return -1: hedef bulunamadı. 3 turda aralık boşaldı; 8 öğenin hepsine tek tek bakılmadı.

int ikiliAra(int[] dizi, int hedef) {
    int sol = 0, sag = dizi.length - 1;
    while (sol <= sag) {
        int orta = sol + (sag - sol) / 2;
        if (dizi[orta] == hedef) return orta;
        if (dizi[orta] < hedef) sol = orta + 1;
        else sag = orta - 1;
    }
    return -1;
}

Arama

Arama Karşılaştırması

ÖzellikDoğrusalİkili
Sıralı veriGerekmezGerekir
En kötü zamanO(n)O(log n)
YapıDizi veya akışRastgele erişimli sıralı yapı
KullanımAz veya sırasız veriÇok sayıda arama
Doğrusal12345678910111213141516hedef son öğe: 16 öğenin hepsine bakılır → 16 karşılaştırmaİkili12345aralık her adımda yarıya iner: 16 → 8 → 4 → 2 → 1 ⇒ 5 karşılaştırma

Arama

Arama: En Kötü Durumda Kaç Karşılaştırma?

016324864016324864dizi boyutu nen kötü karşılaştırmadoğrusal (64)ikili (7)

Değerler iki algoritmanın bulunamayan bir hedefle gerçekten çalıştırılmasıyla sayıldı. n = 1.000.000 için doğrusal 1.000.000, ikili yalnızca 20 tur.

Sıralama

Seçimli Sıralama

  • Sıralanmamış bölümde en küçük öğeyi bulur.
  • Bulunan öğeyi bölümün ilk konumuyla değiştirir.
  • Karşılaştırma sayısı her zaman n(n−1)/2 → O(n²); takas en fazla n − 1; ek bellek O(1).
i = 0'dan n-2'ye kadar
    enK = i
    j = i+1'den n-1'e kadar
        eğer dizi[j] < dizi[enK] ise enK = j
    dizi[i] ile dizi[enK] yer değiştir
i = 02910143713ienKyer değiştirsonra1029143713sıralı | sıralanmamışen küçük (10) bulundu

Sıralama · Adım adım izleme

Seçimli Sıralama Adım Adım

029110214337413▲ ienK

i = 0: sıralanmamış bölüm 0…4. Aday en küçük: dizi[0] = 29.

029110214337413▲ i▲ jenK

dizi[1] = 10 < dizi[0] = 29 → doğru → enK = 1.

029110214337413▲ i▲ j▲ enK

dizi[2] = 14 < dizi[1] = 10 → yanlış.

029110214337413▲ i▲ j▲ enK

dizi[3] = 37 < dizi[1] = 10 → yanlış.

029110214337413▲ i▲ j▲ enK

dizi[4] = 13 < dizi[1] = 10 → yanlış.

010129214337413▲ i▲ enK

dizi[0] ile dizi[1] yer değiştirir → 10 yerine oturdu.

010129214337413▲ ienK

i = 1: sıralanmamış bölüm 1…4. Aday en küçük: dizi[1] = 29.

010129214337413▲ i▲ jenK

dizi[2] = 14 < dizi[1] = 29 → doğru → enK = 2.

010129214337413▲ i▲ j▲ enK

dizi[3] = 37 < dizi[2] = 14 → yanlış.

010129214337413▲ i▲ jenK

dizi[4] = 13 < dizi[2] = 14 → doğru → enK = 4.

010113214337429▲ i▲ enK

dizi[1] ile dizi[4] yer değiştirir → 13 yerine oturdu.

010113214337429▲ ienK

i = 2: sıralanmamış bölüm 2…4. Aday en küçük: dizi[2] = 14.

010113214337429▲ ienK▲ j

dizi[3] = 37 < dizi[2] = 14 → yanlış.

010113214337429▲ ienK▲ j

dizi[4] = 29 < dizi[2] = 14 → yanlış.

010113214337429▲ ienK

En küçük zaten yerinde (enK = i), değişim etkisiz.

010113214337429▲ ienK

i = 3: sıralanmamış bölüm 3…4. Aday en küçük: dizi[3] = 37.

010113214337429▲ i▲ jenK

dizi[4] = 29 < dizi[3] = 37 → doğru → enK = 4.

010113214329437▲ i▲ enK

dizi[3] ile dizi[4] yer değiştirir → 29 yerine oturdu. Dizi sıralandı: 10 karşılaştırma = n(n−1)/2.

i = 0'dan n-2'ye kadar
    enK = i
    j = i+1'den n-1'e kadar
        eğer dizi[j] < dizi[enK] ise enK = j
    dizi[i] ile dizi[enK] yer değiştir

Sıralama

Kabarcık Sıralaması

  • Komşu öğeleri karşılaştırır ve yanlış sıradaysa yer değiştirir.
  • Her turda kalanların en büyüğü sona taşınır; sonraki tur bir öğe kısa olur.
  • Bir turda hiç değişim olmazsa dizi sıralıdır, durulur.
  • Genel durumda O(n²); en iyi durumda (zaten sıralı dizi) tek tur: O(n).
tur = 0
tekrarla
    degisti = yanlış
    j = 0'dan n-2-tur'a kadar
        eğer dizi[j] > dizi[j+1] ise
            dizi[j] ile dizi[j+1] yer değiştir
            degisti = doğru
    tur = tur + 1
degisti yanlış olana kadar

Sıralama · Adım adım izleme

Kabarcık Sıralaması Adım Adım (1. geçiş)

0511243248

tur = 0. Komşu çiftler soldan sağa karşılaştırılacak.

0511243248

1. geçiş: degisti = yanlış; j = 0…3.

0511243248▲ j▲ j+1

dizi[0] = 5 > dizi[1] = 1 → doğru → yer değiştirecek.

0115243248▲ j▲ j+1

Yer değiştirdi: 5 bir sağa kaydı; degisti = doğru.

0115243248▲ j▲ j+1

dizi[1] = 5 > dizi[2] = 4 → doğru → yer değiştirecek.

0114253248▲ j▲ j+1

Yer değiştirdi: 5 bir sağa kaydı; degisti = doğru.

0114253248▲ j▲ j+1

dizi[2] = 5 > dizi[3] = 2 → doğru → yer değiştirecek.

0114223548▲ j▲ j+1

Yer değiştirdi: 5 bir sağa kaydı; degisti = doğru.

0114223548▲ j▲ j+1

dizi[3] = 5 > dizi[4] = 8 → yanlış, sıra doğru.

0114223548

Geçiş bitti: 8 kesin yerinde (yeşil çerçeve). tur = 1.

0114223548

degisti = doğru → yeni geçiş gerekli.

tur = 0
tekrarla
    degisti = yanlış
    j = 0'dan n-2-tur'a kadar
        eğer dizi[j] > dizi[j+1] ise
            dizi[j] ile dizi[j+1] yer değiştir
            degisti = doğru
    tur = tur + 1
degisti yanlış olana kadar

Sıralama · Adım adım izleme

Kabarcık Sıralaması Adım Adım (devam: 2. geçiş)

0114223548

2. geçiş: degisti = yanlış; j = 0…2.

0114223548▲ j▲ j+1

dizi[0] = 1 > dizi[1] = 4 → yanlış, sıra doğru.

0114223548▲ j▲ j+1

dizi[1] = 4 > dizi[2] = 2 → doğru → yer değiştirecek.

0112243548▲ j▲ j+1

Yer değiştirdi: 4 bir sağa kaydı; degisti = doğru.

0112243548▲ j▲ j+1

dizi[2] = 4 > dizi[3] = 5 → yanlış, sıra doğru.

0112243548

Geçiş bitti: 5 kesin yerinde (yeşil çerçeve). tur = 2.

0112243548

degisti = doğru → yeni geçiş gerekli.

tur = 0
tekrarla
    degisti = yanlış
    j = 0'dan n-2-tur'a kadar
        eğer dizi[j] > dizi[j+1] ise
            dizi[j] ile dizi[j+1] yer değiştir
            degisti = doğru
    tur = tur + 1
degisti yanlış olana kadar

Sıralama · Adım adım izleme

Kabarcık Sıralaması Adım Adım (devam: 3. geçiş)

0112243548

3. geçiş: degisti = yanlış; j = 0…1.

0112243548▲ j▲ j+1

dizi[0] = 1 > dizi[1] = 2 → yanlış, sıra doğru.

0112243548▲ j▲ j+1

dizi[1] = 2 > dizi[2] = 4 → yanlış, sıra doğru.

0112243548

Geçiş bitti: 4 kesin yerinde (yeşil çerçeve). tur = 3.

0112243548

degisti = yanlış → hiç değişim olmadı, dizi sıralı; dur. Toplam 9 karşılaştırma.

tur = 0
tekrarla
    degisti = yanlış
    j = 0'dan n-2-tur'a kadar
        eğer dizi[j] > dizi[j+1] ise
            dizi[j] ile dizi[j+1] yer değiştir
            degisti = doğru
    tur = tur + 1
degisti yanlış olana kadar

Sıralama

Eklemeli Sıralama (Insertion Sort)

  • Elde iskambil kâğıdı dizmeye benzer: soldaki bölüm hep sıralıdır.
  • Sıradaki öğe (anahtar) alınır; ondan büyükler birer sağa kaydırılır, anahtar açılan boşluğa konur.
  • En kötü durumda (ters sıralı) O(n²); zaten sıralı dizide her anahtar için tek karşılaştırma: O(n). Ek bellek O(1).
  • Az sayıda ve neredeyse sıralı veride çok hızlıdır.
i = 1'den n-1'e kadar
    anahtar = dizi[i]
    j = i - 1
    j >= 0 ve dizi[j] > anahtar iken
        dizi[j+1] = dizi[j]
        j = j - 1
    dizi[j+1] = anahtar
sıralı bölümanahtar245323455 > 3 ve 4 > 3: birer sağa kaydır2 > 3 değil: dur3 açılan boşluğa yerleşir

Sıralama · Adım adım izleme

Eklemeli Sıralama Adım Adım

0412531anahtar3

i = 1: anahtar = dizi[1] = 3 alınır, yeri boşalır. Sol bölüm (0…0) sıralı. j = 0.

0412531anahtar3

j = 0 ≥ 0 ve dizi[0] = 4 > 3 → doğru.

0142531anahtar3sağa kaydır

4 bir sağa kaydı; boşluk 0. hücreye geçti. j = -1.

0142531anahtar3

j = -1 < 0 → yanlış (sol uca gelindi): döngü biter.

03142531

dizi[0] = 3: anahtar boşluğa yerleşti. Artık 0…1 sıralı.

0314231anahtar5

i = 2: anahtar = dizi[2] = 5 alınır, yeri boşalır. Sol bölüm (0…1) sıralı. j = 1.

0314231anahtar5

j = 1 ≥ 0 ve dizi[1] = 4 > 5 → yanlış: döngü biter.

03142531

dizi[2] = 5: anahtar boşluğa yerleşti. Artık 0…2 sıralı.

0314253anahtar1

i = 3: anahtar = dizi[3] = 1 alınır, yeri boşalır. Sol bölüm (0…2) sıralı. j = 2.

0314253anahtar1

j = 2 ≥ 0 ve dizi[2] = 5 > 1 → doğru.

0314235anahtar1sağa kaydır

5 bir sağa kaydı; boşluk 2. hücreye geçti. j = 1.

0314235anahtar1

j = 1 ≥ 0 ve dizi[1] = 4 > 1 → doğru.

0312435anahtar1sağa kaydır

4 bir sağa kaydı; boşluk 1. hücreye geçti. j = 0.

0312435anahtar1

j = 0 ≥ 0 ve dizi[0] = 3 > 1 → doğru.

0132435anahtar1sağa kaydır

3 bir sağa kaydı; boşluk 0. hücreye geçti. j = -1.

0132435anahtar1

j = -1 < 0 → yanlış (sol uca gelindi): döngü biter.

01132435

dizi[0] = 1: anahtar boşluğa yerleşti. Artık 0…3 sıralı. Dizi sıralandı; 5 karşılaştırma yapıldı.

i = 1'den n-1'e kadar
    anahtar = dizi[i]
    j = i - 1
    j >= 0 ve dizi[j] > anahtar iken
        dizi[j+1] = dizi[j]
        j = j - 1
    dizi[j+1] = anahtar

Sıralama

Sıralama Karşılaştırması

AlgoritmaTemel fikirEn kötüEn iyiEk alan
SeçimliEn küçüğü seç ve yerleştirO(n²)O(n²)O(1)
KabarcıkKomşuları değiştirO(n²)O(n) (erken durma ile)O(1)
EklemeliÖğeyi sıralı bölüme ekleO(n²)O(n)O(1)
BirleştirmeBöl, sırala, birleştirO(n log n)O(n log n)O(n)

Sıralama

Sıralama: Kaç Karşılaştırma Yapılıyor?

0600120018000102030405060dizi boyutu nortalama karşılaştırmaSeçimli (1770)Kabarcık (1739)Eklemeli (955)Birleştirme (281)

Her n için 20 rastgele dizi dört algoritmayla gerçekten sıralandı; ortalamalar çizildi. n = 60'ta seçimli 1770, birleştirme sıralaması yalnızca 281 karşılaştırma yaptı.

Özet

Bölüm Özeti

  • Algoritma, girdiyi çıktıya dönüştüren açık ve sonlu adımlar bütünüdür.
  • Sözde kod algoritmayı belirli bir dile bağlı kalmadan yazar.
  • Elle izleme ve çeşitli test durumları doğruluğu değerlendirmeye yardım eder.
  • Doğrusal arama sıralama istemez; ikili arama sıralı veride aralığı yarılar.
  • Algoritmalar yalnızca sonuçla değil, zaman ve bellek maliyetiyle de karşılaştırılır.

Özet

Kontrol Soruları

  1. İyi bir problem tanımında hangi bilgiler bulunur?
  2. Sözde kod neden programlama dilinden önce kullanılır?
  3. Faktöriyel algoritmasında 0 girdisi nasıl ele alınır?
  4. İkili arama neden sıralı veri ister?
  5. O(n) ile O(log n) neyi karşılaştırır?
  6. Seçimli sıralama ile kabarcık sıralamasının temel farkı nedir?

Özet

Alıştırmalar

  1. Üç sayıyı (a, b, c) küçükten büyüğe yazan sözde kodu yazın; a = 9, b = 2, c = 5 için izleme tablosu çıkarın.
  2. 1'den n'e kadar olan çift sayıların toplamını bulan algoritmayı yazın. n = 0 ve n = 7 için sonucu izleyin.
  3. Faktöriyel algoritmasını n = 21 girildiğinde uyarı verecek şekilde değiştirin (kısıt 0 ≤ n ≤ 20).
  4. [6, 2, 8, 3] dizisini seçimli, kabarcık ve eklemeli sıralamayla elle sıralayın; her birinde kaç karşılaştırma yapıldığını sayın.
  5. [2, 5, 9, 14, 20, 27, 33] dizisinde ikili aramayla 27 ve 4 değerlerini arayın; her turda sol, sag, orta değerlerini yazın.
  6. Bir sayının basamaklarının toplamını (örn. 472 → 13) bulan algoritmayı % ve / işlemleriyle yazın.
İpuçları
  1. İki sayıyı sırala adımını üç kez uygulayın (a-b, b-c, a-b).
  2. i = 2'den başlayıp i = i + 2 ile ilerleyin; n = 7 → 12.
  3. İkili aramada 27 → 2 tur, 4 → 3 tur sonra -1.

Özet

Kaynaklar

  • Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, MIT Press, 2022.
  • Levitin, Introduction to the Design and Analysis of Algorithms, 3. baskı, Pearson, 2012.
  • Sedgewick ve Wayne, Algorithms, 4. baskı, Addison-Wesley, 2011 (kitap sitesi).
  • Sedgewick ve Wayne, Computer Science: An Interdisciplinary Approach, Addison-Wesley, 2016: 4.1 Performance, 4.2 Sorting and Searching.
  • Oracle, Java SE 21 API: java.util.Arrays (sort, binarySearch).

Son

Algoritmalar
Sonraki sunum: Akış Diyagramları · Çalışma soruları · Simülatörler: Sıralama Algoritmaları Görselleştirici, Akış Diyagramı Yürütücü · Terim sözlüğü
1 / 1Sercan KÜLCÜ, Tüm hakları saklıdır.