Bölüm 2: Diziler

Bölüm 2: Diziler · Çalışma Soruları
Referans ve kopyaAraya eklemeİki işaretçiTek geçişte aramaBellek düzeni
Klasik · çoktan seçmeli · adım adım çalıştırmalı · ucu açık sorular. Önce kendiniz çözün, sonra cevabı açın. · Sercan KÜLCÜ

Klasik Soru · Diziler

Soru 1: Dizi Referansları

Programın çıktısı nedir? Baştaki new int[5] nesnesine ne olur?

int[] a = new int[5];
int[] b = {4, 7, 1, 7, 3};
a = b;
b[2] = 9;
int[] c = b.clone();
c[0] = 0;
System.out.println(a[2] + " " + a[0] + " "
                 + c[2] + " " + a.length);
Cevabı göster

Çıktı: 9 4 9 5

  • a = b sonrası iki değişken aynı diziyi gösterir; b[2] = 9 → a[2] = 9.
  • clone() yeni bir dizi oluşturur (sığ kopya): c[0] değişimi a/b'yi etkilemez; c[2] kopyalandığında zaten 9'du.
  • a.length artık b'nin uzunluğu: 5.
  • İlk new int[5] dizisine hiçbir referans kalmaz; çöp toplayıcı (GC) tarafından temizlenir.

Klasik Soru · Diziler

Soru 2: Sıralı Diziye Araya Ekleme

dizi kapasitesi 7, ilk boyut elemanı sıralıdır. Elemanı sırayı bozmadan ekleyen metodu tamamlayınız. {3, 8, 12, 20, 25} dizisine 10 eklenirken kaç kaydırma yapılır?

// d: dizi, n: dolu eleman sayısı
int siraliEkle(int[] d, int n, int x) {
    if (n == d.length) return n;   // dolu
    // ... tamamlayınız
}
Cevabı göster
int siraliEkle(int[] d, int n, int x) {
    if (n == d.length) return n;
    int i = n - 1;
    while (i >= 0 && d[i] > x) {
        d[i + 1] = d[i];    // sağa kaydır
        i--;
    }
    d[i + 1] = x;
    return n + 1;
}

25, 20, 12 sağa kayar: 3 kaydırma → {3, 8, 10, 12, 20, 25}.

En kötü durum (x en küçük): n kaydırma → O(n). Sona ekleme O(1) olsa da araya ekleme diziler için pahalıdır.

Klasik Soru · Diziler

Soru 3: İki Sıralı Dizide Ortak Elemanlar

İki sıralı dizideki ortak elemanları O(n + m) zamanda yazdıran metodu yazınız. İç içe iki döngülü çözümle karşılaştırınız.

int[] d1 = {1, 3, 4, 7, 9};
int[] d2 = {2, 3, 7, 8, 9};
ortaklariYaz(d1, d2);   // 3 7 9
Cevabı göster
void ortaklariYaz(int[] d1, int[] d2) {
    int i = 0, j = 0;
    while (i < d1.length && j < d2.length) {
        if (d1[i] < d2[j]) i++;
        else if (d1[i] > d2[j]) j++;
        else {
            System.out.print(d1[i] + " ");
            i++; j++;
        }
    }
}

Her adımda i veya j ilerler → en fazla n + m adım: O(n + m).

İç içe döngü her çifti dener: O(n · m). Sıralılık bilgisi kullanılınca gereksiz karşılaştırmalar atlanır.

Klasik Soru · Diziler

Soru 4: İkinci En Büyük Eleman

Diziyi sıralamadan, tek geçişte ikinci en büyük (birinciden farklı) elemanı döndüren metodu yazınız. {12, 35, 1, 10, 35, 34} için sonuç nedir?

İpucu: iki değişken tutun: enBuyuk ve ikinci. Her eleman için hangisinin güncelleneceğine karar verin.

Cevabı göster
int ikinciEnBuyuk(int[] d) {
    int enBuyuk = Integer.MIN_VALUE;
    int ikinci = Integer.MIN_VALUE;
    for (int x : d) {
        if (x > enBuyuk) {
            ikinci = enBuyuk;
            enBuyuk = x;
        } else if (x > ikinci && x != enBuyuk) {
            ikinci = x;
        }
    }
    return ikinci;
}

Sonuç: 34 (35 iki kez geçse de birinciyle aynı olduğu için sayılmaz). Zaman O(n), ek bellek O(1).

Klasik Soru · Diziler

Soru 5: Dizilerde Erişim ve Ekleme Maliyeti

(a) int[] d = new int[100] dizisi 1000 adresinden başlıyorsa d[25] hangi adrestedir (int = 4 bayt)? Bu neden O(1)'dir?
(b) Aynı dizinin başına eleman eklemek neden O(n)'dir?
(c) int[] a = new int[3]; ile int[] b = {1, 2, 3}; arasındaki fark nedir?

Cevabı göster
  • (a) adres = başlangıç + indis × eleman boyutu = 1000 + 25 × 4 = 1100. Elemanlar ardışık durduğu için tek bir çarpma ve toplama yeter; dizinin boyutundan bağımsızdır → O(1).
  • (b) Ardışıklığı korumak için 0..n−1 arasındaki tüm elemanlar bir sağa kaydırılmalıdır → n işlem, O(n). Kapasite doluysa ayrıca yeni diziye kopyalama gerekir.
  • (c) İkisi de heap'te 3 elemanlı int[] nesnesi oluşturur. new int[3] elemanları varsayılan değerle (0) doldurur; {1, 2, 3} ilk değer listesiyle doldurur ve yalnızca tanımlama satırında yazılabilir (sonradan b = new int[]{4, 5}; gerekir).

Çoktan Seçmeli · Diziler

Test 1

Kodun çıktısı nedir?

int[] a = {3, 1, 4};
int[] b = a;
b[1] = 9;
System.out.print(a[1]);

b, a ile aynı dizi nesnesini gösterir; b[1] = 9 değişikliği a üzerinden de görülür.

1000 elemanlı sıralı bir dizide ikili arama (binary search) en kötü durumda yaklaşık kaç karşılaştırma yapar?

Her adımda arama aralığı yarıya iner: 2¹⁰ = 1024 ≥ 1000 → en fazla ≈ 10 karşılaştırma. Doğrusal arama 1000 yapabilirdi.

Çoktan Seçmeli · Diziler

Test 2

int[][] m = new int[3][4]; için m.length + m[0].length nedir?

m.length satır sayısıdır (3), m[0].length ilk satırın uzunluğudur (4): 3 + 4 = 7. Java'da 2B dizi, dizilerin dizisidir.

n elemanlı bir dizide hangi işlem O(n) zaman alır?

Başa ekleme tüm elemanları bir sağa kaydırmayı gerektirir → O(n). Diğerleri O(1).

Adım Adım Çalıştırma · Diziler

Diziyi Yerinde Ters Çevirme

İki işaretçi ile ters çevirme kodunu adım adım izleyin. Kaç takas yapılır?

4081152163234

Önce tahmin edin: dizinin son hâli ne olur?

4081152163234

Dizi oluşturulur.

40i81152163234j

i baştan, j sondan başlar.

40i81152163234j

0 < 4 → döngüye girilir.

230i8115216344j

d[0] ile d[4] yer değiştirir (t geçici değişken).

23081i152163j44

İşaretçiler birbirine yaklaşır.

23081i152163j44

1 < 3 → devam.

230161i15283j44

d[1] ile d[3] yer değiştirir.

230161152i, j8344

i ve j ortada buluşur.

230161152i, j8344

2 < 2 yanlış → döngü biter. Ortadaki 15 yerinde kalır.

2301611528344

⌊n/2⌋ = 2 takas: O(n) zaman, O(1) ek bellek.

int[] d = {4, 8, 15, 16, 23};
int i = 0, j = d.length - 1;
while (i < j) {
    int t = d[i];
    d[i] = d[j];
    d[j] = t;
    i++; j--;
}
System.out.println(Arrays.toString(d));

Ucu Açık Soru · Diziler

Kaç Öğrenci Gelecek?

  1. Bir not sisteminde dönem başında kaç öğrencinin kaydolacağı bilinmiyor. Notları sabit boyutlu dizi mi, dinamik dizi (ArrayList) mi ile tutarsınız? Neden?
  2. Dinamik dizi dolduğunda kapasiteyi 2 katına çıkarmak ile 10 artırmak arasındaki farkı n ekleme için toplam kopyalama maliyeti üzerinden karşılaştırın.
Örnek cevap ve değerlendirme ölçütleri

1. Boyut bilinmediği için dinamik dizi uygundur. Sabit dizi ya fazla büyük seçilip bellek israf eder ya da küçük kalıp taşar. Dinamik dizi indisle O(1) erişimi korur, gerektiğinde büyür.

2. 2 katı: kopyalar 1 + 2 + 4 + … + n/2 < n → toplam O(n), ekleme başına amortize O(1). +10: kopyalar 10 + 20 + 30 + … ≈ n²/20 → toplam O(n²), ekleme başına O(n). Bedel: katlamada en fazla ≈ %50 boş kapasite kalabilir (bellek–zaman dengesi). Java ArrayList ≈ 1,5 kat büyür.

Değerlendirme: boyut belirsizliği gerekçesi · iki stratejinin toplam maliyet hesabı · amortize analiz kavramı · bellek israfına değinme.

Son

Bölüm 2: Diziler: Çalışma Soruları
Konu anlatımı: Diziler sunumu
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.