Bölüm 10: Diziler
Giriş
Öğrenme Çıktıları
Dizi bildirmek ve ilk değer vermek.
İndis ve length kullanmak.
Diziyi döngülerle gezmek ve dönüştürmek.
İki boyutlu dizilerle satır-sütun işlemleri yapmak.
Temeller
Dizi Nedir?
- Aynı tipte, sabit sayıda öğeyi tek nesnede ardışık hücrelerde saklar.
- Öğelere sıfır tabanlı indisle erişilir:
sayilar[0]…sayilar[4]. - Uzunluk (
length) oluşturulduktan sonra değişmez. - Dizi değişkeni öğeleri değil, heap'teki dizi nesnesinin referansını (adresini) tutar.
Değişken → dizi nesnesi (referans oku)
Temeller
Dizi ve İndis
- İlk indis 0, son indis length − 1'dir (5 öğe → 0…4).
a[i]adresi doğrudan hesaplanır (başlangıç + i × hücre boyu); bu yüzden erişim diziyi gezmeden, sabit sürede (O(1)) olur.
Temeller
Avantaj ve Sınır
| Avantaj | Sınır |
|---|---|
| İndisle hızlı erişim | Boyut sabittir |
| Öğe tipi tutarlıdır | Araya ekleme maliyetlidir |
| Döngüyle kolay işlenir | Sınır aşımı çalışma zamanı hatasıdır |
| Bellekte düzenli yapı | Tek bir öğe tipi tutar |
Bildirim
Dizi Oluşturma
int[] sayilar = new int[5]; String[] adlar = {"Ada", "Can", "Ece"}; double[] olcumler; olcumler = new double[10];
newile oluşturulan dizinin hücreleri tipin varsayılan değerini alır (sağda).- İlklendirici
{…}kullanılınca uzunluk değer sayısından çıkarılır (adlar.length = 3).
Varsayılan başlangıç değerleri
Bildirim · Kodu adım adım çalıştır
Kod İzleme: Dizi Oluşturma
Bildirim: yığında yalnızca sayilar adlı referans değişkeni açılır; henüz bir dizi yok.
new int[4] heap'te 4 hücreli dizi oluşturur, hepsi 0. Değişkene dizinin referansı yazılır (ok).
sayilar[0] = 7: ok izlenir, 0 numaralı hücreye 7 yazılır.
sayilar[3] = 2: son hücre (indis length − 1 = 3) güncellenir.
İlklendirici {…}: 3 değer var → uzunluk 3 olan dizi kurulur ve adlar onu gösterir.
length bir alandır (parantez yok): 4 ve 3 yazılır.
int[] sayilar; sayilar = new int[4]; sayilar[0] = 7; sayilar[3] = 2; String[] adlar = {"Ada", "Can", "Ece"}; System.out.println(sayilar.length + " " + adlar.length);
Erişim · Kodu adım adım çalıştır
Öğe Okuma ve Yazma
Üç öğeli dizi oluşur; indisler 0, 1, 2.
Okuma: puanlar[0] ilk hücredeki değeri verir → ilk = 70.
Yazma: atamanın solundaki puanlar[1] hücrenin kendisidir; 85 silinir, 88 yazılır.
puanlar.length - 1 = 3 − 1 = 2 → son öğe 90. Dizi boyu değişse de kod doğru kalır.
İki değer aralarında boşlukla yazdırılır.
int[] puanlar = {70, 85, 90}; int ilk = puanlar[0]; puanlar[1] = 88; int son = puanlar[puanlar.length - 1]; System.out.println(ilk + " " + son);
Erişim
Sınır Dışı Hatası
- Geçerli indisler 0 ile length − 1 arasındadır; negatif indis ve
length'in kendisi geçersizdir. - Derleyici bunu yakalamaz; program çalışırken
ArrayIndexOutOfBoundsExceptionile durur.
i < dizi.length olmalıdır; <= bir tur fazla döner.Erişim · Kodu adım adım çalıştır
Kod İzleme: Bir Tur Fazla (<=)
Uzunluğu 3 olan dizi: geçerli indisler 0, 1, 2.
0 <= 3 → true, gövdeye girilir.
a[0] = 4 yazdırılır.
i++ → 1 <= 3 → true, gövdeye girilir.
a[1] = 8 yazdırılır.
i++ → 2 <= 3 → true, gövdeye girilir.
a[2] = 6 yazdırılır.
i++ → 3 <= 3 → true — dikkat: 3 geçersiz indis ama koşul yine de doğru!
a[3]: böyle bir hücre yok → program hata ile durur. Çözüm: koşulu i < a.length yapmak.
int[] a = {4, 8, 6}; for (int i = 0; i <= a.length; i++) { System.out.println(a[i]); }
Döngüler · Kodu adım adım çalıştır
Klasik for ile Gezinme
Dizi hazır; i indis olarak 0'dan başlayacak.
int i = 0; 0 < 3 → true
puanlar[0] = 70; %d: %d kalıbı 0: 70 üretir.
i++ → 1 < 3 → true
puanlar[1] = 88; %d: %d kalıbı 1: 88 üretir.
i++ → 2 < 3 → true
puanlar[2] = 90; %d: %d kalıbı 2: 90 üretir.
i++ → 3 < 3 → false → döngü biter; i = length olduğu için a[i]'ye hiç erişilmez.
int[] puanlar = {70, 88, 90}; for (int i = 0; i < puanlar.length; i++) { System.out.printf("%d: %d%n", i, puanlar[i]); }
İndis gerektiğinde (konum yazdırmak, komşu öğeye bakmak, hücreye yazmak) klasik for kullanılır.
Döngüler · Kodu adım adım çalıştır
Gelişmiş for (for-each)
Gelişmiş for dizinin öğelerini sırayla verir; indis yoktur.
1. tur: puan'a puanlar[0]'ın kopyası (70) konur.
puan = 75 olur; dizideki hücre 70 olarak kalır — değişen yalnızca kopya.
75 yazdırılır.
2. tur: puan'a puanlar[1]'in kopyası (88) konur.
puan = 93 olur; dizideki hücre 88 olarak kalır — değişen yalnızca kopya.
93 yazdırılır.
3. tur: puan'a puanlar[2]'nin kopyası (90) konur.
puan = 95 olur; dizideki hücre 90 olarak kalır — değişen yalnızca kopya.
95 yazdırılır.
Öğe kalmadı → döngü biter; puan değişkeni kapsam dışına çıkar.
puanlar[0] hâlâ 70: gelişmiş for'da döngü değişkenine atama diziyi değiştirmez.
int[] puanlar = {70, 88, 90}; for (int puan : puanlar) { puan = puan + 5; System.out.println(puan); } System.out.println(puanlar[0]);
İşlemler · Kodu adım adım çalıştır
Toplam ve Ortalama
Dört öğeli dizi.
Biriktirici toplam = 0 ile başlar.
deger = 4 → toplam += deger: 0 + 4 = 4.
deger = 7 → toplam += deger: 4 + 7 = 11.
deger = 2 → toplam += deger: 11 + 2 = 13.
deger = 6 → toplam += deger: 13 + 6 = 19.
Döngü bitti. ortalama 0 ile başlatılır (boş dizi için güvenli değer).
4 > 0 → true: dizi boş değil, bölme yapılabilir.
(double) 19 / 4 = 4.75. Dönüşüm olmasa tam sayı bölmesi 4 verirdi.
Sonuçlar yazdırılır.
int[] sayilar = {4, 7, 2, 6}; int toplam = 0; for (int deger : sayilar) toplam += deger; double ortalama = 0; if (sayilar.length > 0) ortalama = (double) toplam / sayilar.length; System.out.println(toplam + " " + ortalama);
İşlemler · Kodu adım adım çalıştır
En Küçük ve En Büyük
Dizi: 5, 3, 9, 1.
İlk öğe hem min hem max adayıdır (0 ile başlatmak negatif/pozitif dizilerde yanlış sonuç verirdi).
1. tur: deger = 5.
5 < 5 → false; min değişmez.
5 > 5 → false; max değişmez.
2. tur: deger = 3.
3 < 5 → true: min = 3.
3 > 5 → false; max değişmez.
3. tur: deger = 9.
9 < 3 → false; min değişmez.
9 > 5 → true: max = 9.
4. tur: deger = 1.
1 < 3 → true: min = 1.
1 > 9 → false; max değişmez.
Tüm öğelere bakıldı (n = 4 tur) → 1 9.
int[] sayilar = {5, 3, 9, 1}; int min = sayilar[0], max = sayilar[0]; for (int deger : sayilar) { if (deger < min) min = deger; if (deger > max) max = deger; } System.out.println(min + " " + max);
Boş dizide sayilar[0] hata verir; gerçek kodda önce sayilar.length == 0 durumu ele alınmalıdır.
İşlemler · Kodu adım adım çalıştır
Diziyi Ters Çevirme (iki işaretçi)
Tersine çevrilecek dizi.
İki işaretçi: sol = 0 ve sag = length − 1 = 4.
0 < 4 → true, uçlar yer değiştirecek.
gecici = dizi[0] = 1: soldaki değer kaybolmasın diye saklanır.
dizi[0] = dizi[4] → sol hücreye 5 yazılır.
dizi[4] = gecici → sağ hücreye 1. Takas tamam.
İşaretçiler merkeze yaklaşır: sol = 1, sag = 3.
1 < 3 → true, uçlar yer değiştirecek.
gecici = dizi[1] = 2: soldaki değer kaybolmasın diye saklanır.
dizi[1] = dizi[3] → sol hücreye 4 yazılır.
dizi[3] = gecici → sağ hücreye 2. Takas tamam.
İşaretçiler merkeze yaklaşır: sol = 2, sag = 2.
2 < 2 → false: işaretçiler ortada buluştu → dizi ters çevrildi.
int[] dizi = {1, 2, 3, 4, 5}; int sol = 0, sag = dizi.length - 1; while (sol < sag) { int gecici = dizi[sol]; dizi[sol] = dizi[sag]; dizi[sag] = gecici; sol++; sag--; }
n/2 takas yapılır; ek dizi gerekmez (yerinde, O(1) ek alan).
İşlemler · Kodu adım adım çalıştır
Ortalamanın Üstündekileri Sayma
Beş öğrencinin notu. Önce ortalama, sonra ortalamanın üstündekiler: iki geçiş gerekir.
1. geçiş: toplam biriktirilir.
x = 60 → toplam = 60.
x = 75 → toplam = 135.
x = 90 → toplam = 225.
x = 45 → toplam = 270.
x = 80 → toplam = 350.
(double) 350 / 5 = 70.0.
2. geçiş için sayaç: ustte = 0.
60 > 70.0 → false.
75 > 70.0 → true: ustte = 1.
90 > 70.0 → true: ustte = 2.
45 > 70.0 → false.
80 > 70.0 → true: ustte = 3.
Ortalama 70.0, üstünde 3 not var.
int[] notlar = {60, 75, 90, 45, 80}; int toplam = 0; for (int x : notlar) toplam += x; double ort = (double) toplam / notlar.length; int ustte = 0; for (int x : notlar) if (x > ort) ustte++; System.out.println(ort + " " + ustte);
İşlemler · Kodu adım adım çalıştır
Dizideki En Büyük İkinci Öğe
İki aday en küçük int değeriyle (Integer.MIN_VALUE) başlar; her öğe bir kez incelenir.
7 > MIN → yeni en büyük: eski en büyük (MIN) ikinciye iner, enBuyuk = 7.
12 > 7 → yeni en büyük: eski en büyük (7) ikinciye iner, enBuyuk = 12.
Değişiklik yok: 5 ikinciden (7) büyük değil.
Değişiklik yok: 12 == enBuyuk (tekrar), sayılmaz.
9 en büyükten küçük ama ikinciden büyük ve 9 != 12 → ikinci = 9.
Tek geçişte sonuç: 9 (12 iki kez geçse de ikinci en büyük 9'dur).
int[] a = {7, 12, 5, 12, 9}; int enBuyuk = Integer.MIN_VALUE; int ikinci = Integer.MIN_VALUE; for (int x : a) { if (x > enBuyuk) { ikinci = enBuyuk; enBuyuk = x; } else if (x > ikinci && x != enBuyuk) { ikinci = x; } } System.out.println(ikinci);
İşlemler · Kodu adım adım çalıştır
Frekans Sayma: Zar Histogramı
Atışlar sabit verildi (gerçekte rastgele.nextInt(6) + 1). 7 hücreli sayaç: indis = zar değeri (0 kullanılmaz). Bu, değeri indis olarak kullanma hilesidir.
zar = 3 → sayac[3]++ → 1. if-else zincirine gerek yok!
zar = 6 → sayac[6]++ → 1. if-else zincirine gerek yok!
zar = 3 → sayac[3]++ → 2. if-else zincirine gerek yok!
zar = 1 → sayac[1]++ → 1. if-else zincirine gerek yok!
zar = 6 → sayac[6]++ → 2. if-else zincirine gerek yok!
zar = 3 → sayac[3]++ → 3. if-else zincirine gerek yok!
y = 1: sayac[1] = 1 kadar yıldız.
y = 2: sayac[2] = 0 kadar yıldız (hiç yok).
y = 3: sayac[3] = 3 kadar yıldız.
y = 4: sayac[4] = 0 kadar yıldız (hiç yok).
y = 5: sayac[5] = 0 kadar yıldız (hiç yok).
y = 6: sayac[6] = 2 kadar yıldız.
int[] atislar = {3, 6, 3, 1, 6, 3}; int[] sayac = new int[7]; for (int zar : atislar) sayac[zar]++; for (int y = 1; y <= 6; y++) { System.out.print(y + ": "); for (int k = 0; k < sayac[y]; k++) System.out.print("*"); System.out.println(); }
İşlemler · Kodu adım adım çalıştır
Eratosthenes Eleği (boolean dizi)
Tüm hücreler false: başlangıçta 2…20 hepsi asal adayı.
2 × 2 = 4 <= 20 → true.
2 elenmemiş → asal. Katları 2·2'den başlayarak işaretlenir: k = 4, 6, 8, 10, 12, 14, 16, 18, 20.
3 × 3 = 9 <= 20 → true.
3 elenmemiş → asal. Katları 3·3'ten başlayarak işaretlenir: k = 9, 12, 15, 18.
4 × 4 = 16 <= 20 → true.
asalDegil[4] = true → 4 zaten elenmiş, katlarına bakmaya gerek yok.
5 × 5 = 25 <= 20 → false: √20'den büyük bölen aramaya gerek yok.
Elenmemiş olanlar yazdırılır: 8 asal.
int n = 20; boolean[] asalDegil = new boolean[n + 1]; for (int i = 2; i * i <= n; i++) if (!asalDegil[i]) for (int k = i * i; k <= n; k += i) asalDegil[k] = true; for (int i = 2; i <= n; i++) if (!asalDegil[i]) System.out.print(i + " ");
İşlemler
Dizi Kopyalama
b = aöğeleri değil referansı kopyalar: iki ok aynı nesneyi gösterir.- Bağımsız kopya için
a.clone(),Arrays.copyOf(a, a.length)veyaSystem.arraycopy. - Nesne dizilerinde bu yöntemler öğe referanslarını kopyalar; nesnelerin kendisi çoğaltılmaz (sığ kopya).
İşlemler · Kodu adım adım çalıştır
Kod İzleme: Referans Kopyası ve Öğe Kopyası
Heap'te bir dizi; a onu gösterir.
b = a: yeni dizi oluşmaz; b'ye aynı referans yazılır → iki ok aynı nesnede.
b[0] = 99: b'nin gösterdiği nesne değişti — bu, a'nın da nesnesi!
a[0] artık 99. Referans kopyası bağımsız bir dizi değildir.
a.clone() heap'te yeni bir dizi açar ve öğeleri tek tek kopyalar.
c[1] = 50 yalnızca kopyayı değiştirir.
a[1] = 2 (değişmedi), c[1] = 50.
int[] a = {1, 2, 3}; int[] b = a; b[0] = 99; System.out.println(a[0]); int[] c = a.clone(); c[1] = 50; System.out.println(a[1] + " " + c[1]);
İşlemler
Arrays Yardımcıları
import java.util.Arrays; int[] a = {5, 2, 9}, r = {10, 20, 30, 40, 50}, p = {1, 2, 3}, q = {1, 2, 3}, f = new int[4]; int[][] m = {{1, 2}, {3, 4}};
| Çağrı | Sonuç |
|---|---|
Arrays.toString(a) | [5, 2, 9] |
Arrays.deepToString(m) | [[1, 2], [3, 4]] |
Arrays.toString(m) | [[I@… (adres) |
Arrays.fill(f, 7) → f | [7, 7, 7, 7] |
p == q / p.equals(q) | false / false |
Arrays.equals(p, q) | true |
| Kopya (Arrays.) | Sonuç |
|---|---|
copyOf(a, 5) | [5, 2, 9, 0, 0] |
copyOf(a, 2) | [5, 2] |
copyOfRange(r, 1, 4) | [20, 30, 40] |
==veequalsreferansı karşılaştırır; içerik içinArrays.equals(2B içindeepEquals).copyOfuzunluk büyükse sıfırla doldurur, küçükse keser;copyOfRange'te bitiş indisi dahil değildir.
Arama
Doğrusal Arama: ara(d, 6)
static int ara(int[] dizi, int hedef) { for (int i = 0; i < dizi.length; i++) if (dizi[i] == hedef) return i; return -1; } // main içinde: int[] d = {8, 3, 6, 2}; System.out.println(ara(d, 6));
| i | dizi[i] | == 6 ? |
|---|---|---|
| 0 | 8 | false |
| 1 | 3 | false |
| 2 | 6 | true → return 2 |
- Çıktı: 2. İlk eşleşmede döngü erken biter.
diziparametresidile aynı diziyi gösterir (referans aktarılır); kopya oluşmaz.- Hedef yoksa n karşılaştırmadan sonra −1 döner → O(n).
Arama
Sıralama ve İkili Arama
Arrays.sort(a)diziyi küçükten büyüğe yerinde sıralar (özgün sıra kaybolur).Arrays.binarySearch(a, x)yalnızca sıralı dizide doğru çalışır; bulursa indisi döndürür; bulamazsa-(eklenme noktası) - 1gibi negatif bir değer döndürür.- Her adımda aralığı yarıya indirdiği için doğrusal aramadan çok daha az karşılaştırma yapar.
- İkisi için de
import java.util.Arrays;gerekir.
Arama
Ortanca (Medyan)
- Ortanca: sıralanmış dizinin ortasındaki değer; öğe sayısı çiftse ortadaki ikisinin ortalaması.
- Uç değerden etkilenmez: {1, 2, 3, 4, 100} için ortalama 22.0, ortanca 3.
Arrays.sortdiziyi yerinde değiştirir; bu yüzden kopya sıralanır.
int[] a = {7, 3, 9, 1, 5}; int[] s = Arrays.copyOf(a, a.length); Arrays.sort(s); // a bozulmaz int n = s.length; double m = (n % 2 == 1) ? s[n / 2] : (s[n/2 - 1] + s[n/2]) / 2.0; System.out.println(m); // 5.0
Sıralama
Kabarcık Sıralaması (Bubble Sort)
int[] a = {5, 1, 4, 2}; int n = a.length; for (int gecis = 0; gecis < n - 1; gecis++) { for (int j = 0; j < n - 1 - gecis; j++) { if (a[j] > a[j + 1]) { int gecici = a[j]; a[j] = a[j + 1]; a[j + 1] = gecici; } } }
| geçiş | geçiş sonu dizi | karş. | takas |
|---|---|---|---|
| 1 | [1, 4, 2, 5] | 3 | 3 |
| 2 | [1, 2, 4, 5] | 2 | 1 |
| 3 | [1, 2, 4, 5] | 1 | 0 |
- Her geçişte kalanların en büyüğü sona yerleşir; iç döngü her geçişte bir kısalır.
- Toplam 3 + 2 + 1 = 6 karşılaştırma → O(n²).
- 3. geçişte hiç takas yok: dizi 2. geçişten sonra sıralıydı.
Sıralama
Eklemeli Sıralama (Insertion Sort)
int[] a = {4, 3, 5, 1}; for (int i = 1; i < a.length; i++) { int anahtar = a[i]; int j = i - 1; while (j >= 0 && a[j] > anahtar) { a[j + 1] = a[j]; j--; } a[j + 1] = anahtar; }
| i | anahtar | sağa kayanlar | tur sonu dizi |
|---|---|---|---|
| 1 | 3 | 4 | [3, 4, 5, 1] |
| 2 | 5 | — | [3, 4, 5, 1] |
| 3 | 1 | 5, 4, 3 | [1, 3, 4, 5] |
- Sol bölüm hep sıralıdır; anahtardan büyük öğeler birer sağa kayar, anahtar açılan yere konur.
- Neredeyse sıralı dizide çok hızlı; en kötü durumda (ters sıralı) O(n²).
Arama
İkili Arama: hedef = 23
int[] a = {2, 5, 8, 12, 16, 23, 38, 56}; int hedef = 23, lo = 0, hi = a.length - 1; int sonuc = -1; while (lo <= hi) { int mid = (lo + hi) / 2; if (a[mid] == hedef) { sonuc = mid; break; } if (a[mid] < hedef) lo = mid + 1; else hi = mid - 1; } System.out.println(sonuc);
| tur | lo | hi | mid | a[mid] | karar |
|---|---|---|---|---|---|
| 1 | 0 | 7 | 3 | 12 | 12 < 23 → lo = 4 |
| 2 | 4 | 7 | 5 | 23 | bulundu: sonuc = 5 |
- Çıktı: 5. Dizi sıralı olmalıdır.
- 2 turda bulundu; doğrusal arama 6 karşılaştırma yapardı → O(log n).
Arama
Başarısız Arama: Arrays.binarySearch(a, 5) → -3
static int ara(int[] a, int x) { int lo = 0, hi = a.length - 1; while (lo <= hi) { int mid = (lo + hi) / 2; if (a[mid] == x) return mid; if (a[mid] < x) lo = mid + 1; else hi = mid - 1; } return -(lo + 1); } System.out.println(ara(new int[]{2, 4, 6, 8}, 5));
| tur | lo | hi | mid | a[mid] | karar |
|---|---|---|---|---|---|
| 1 | 0 | 3 | 1 | 4 | 4 < 5 → lo = 2 |
| 2 | 2 | 3 | 2 | 6 | 6 > 5 → hi = 1 |
| — | 2 | 1 | lo > hi: döngü biter |
- Sonuç
-(lo + 1)= -3; negatif değer “yok” demektir. - Ekleme noktası = -(-3) - 1 = 2: 5 dizide 2 numaralı konuma girerdi.
Arrays.binarySearchda aynı değeri döndürür.
Analiz
Temel Karmaşıklıklar
| İşlem | Zaman |
|---|---|
| İndisle erişim | O(1) |
| Doğrusal arama | O(n) |
| Sona kadar gezinme | O(n) |
| Ortaya ekleme / silme | O(n) |
| İki iç içe tam gezinme | O(n²) |
Matris
İki Boyutlu Dizi
int[][] matris = { {1, 2, 3}, {4, 5, 6} }; int deger = matris[1][2]; // 6
- İlk indis satır, ikinci indis sütun.
- Java'da çok boyutlu dizi, dizilerin dizisidir: dış dizinin her hücresi bir satır dizisini gösterir; satırlar farklı uzunlukta olabilir (düzensiz dizi).
matris.length= satır sayısı,matris[0].length= sütun sayısı.
Matris · Kodu adım adım çalıştır
Düzensiz (Jagged) Dizi: new int[3][]
new int[3][] yalnızca dış diziyi (3 hücre) oluşturur. Satırlar henüz yok: üç hücre de null.
m[0] = new int[1]: ilk hücre 1 öğeli bir satır gösterir. m[1] ve m[2] hâlâ null.
m[1] = new int[2]: ikinci satır 2 öğeli.
m[2] = new int[3]: satırlar farklı uzunlukta, yani düzensiz (jagged) dizi. Her satır ayrı bir nesnedir.
i = 0: m[0].length = 1 yazılır.
i = 1: m[1].length = 2 yazılır.
i = 2: m[2].length = 3. Çıktı: 1 2 3. Satır null iken m[i].length yazılsaydı NullPointerException olurdu.
int[][] m = new int[3][]; m[0] = new int[1]; m[1] = new int[2]; m[2] = new int[3]; for (int i = 0; i < m.length; i++) System.out.print(m[i].length + " ");
Matris · Kodu adım adım çalıştır
2B Dizide Sığ Kopya Tuzağı
a, iki satır dizisini gösteren bir dış dizidir.
a.clone() yalnızca dış diziyi kopyalar: iki dış dizi, aynı satır nesnelerini gösterir (sığ kopya).
b[0][0] = 99: b[0] ve a[0] aynı satırdır → a[0][0] da 99 oldu.
b[1] = new int[]{7, 8} yalnızca b'nin hücresini yeni satıra bağlar; a[1] değişmez.
a: ortak satır 0 değişti (99), satır 1 hâlâ {3, 4}.
Gerçek kopya için her satır ayrıca kopyalanır: b[i] = a[i].clone().
int[][] a = {{1, 2}, {3, 4}}; int[][] b = a.clone(); b[0][0] = 99; b[1] = new int[]{7, 8}; System.out.println(Arrays.deepToString(a)); System.out.println(Arrays.deepToString(b));
Matris · Kodu adım adım çalıştır
Matriste Satır Satır Gezinme
2 satır × 3 sütunluk matris; matris.length = 2.
Dış döngü: 0 < 2 → true → 0. satır işlenecek.
İç döngü: 0 < 3 → true; matris[0][0] = 1 yazılır (print: satır atlamaz).
İç döngü: 1 < 3 → true; matris[0][1] = 2 yazılır (print: satır atlamaz).
İç döngü: 2 < 3 → true; matris[0][2] = 3 yazılır (print: satır atlamaz).
3 < 3 → false: satır bitti, iç döngüden çıkılır.
println() alt satıra geçer; ardından i++.
Dış döngü: 1 < 2 → true → 1. satır işlenecek.
İç döngü: 0 < 3 → true; matris[1][0] = 4 yazılır (print: satır atlamaz).
İç döngü: 1 < 3 → true; matris[1][1] = 5 yazılır (print: satır atlamaz).
İç döngü: 2 < 3 → true; matris[1][2] = 6 yazılır (print: satır atlamaz).
3 < 3 → false: satır bitti, iç döngüden çıkılır.
println() alt satıra geçer; ardından i++.
Dış döngü: 2 < 2 → false → bitti. Toplam 2 × 3 = 6 hücre gezildi.
int[][] matris = {{1, 2, 3}, {4, 5, 6}}; for (int i = 0; i < matris.length; i++) { for (int j = 0; j < matris[i].length; j++) { System.out.print(matris[i][j] + " "); } System.out.println(); }
Matris · Kodu adım adım çalıştır
Matris Transpozu
Kaynak matris 2 × 3.
matris.length = satır sayısı = 2.
matris[0].length = ilk satırın uzunluğu = 3.
Hedef t boyutları ters: 3 × 2, hücreler 0.
t[0][0] = matris[0][0] = 1: satır ↔ sütun yer değiştirir.
t[1][0] = matris[0][1] = 2: satır ↔ sütun yer değiştirir.
t[2][0] = matris[0][2] = 3: satır ↔ sütun yer değiştirir.
t[0][1] = matris[1][0] = 4: satır ↔ sütun yer değiştirir.
t[1][1] = matris[1][1] = 5: satır ↔ sütun yer değiştirir.
t[2][1] = matris[1][2] = 6: satır ↔ sütun yer değiştirir.
Döngüler bitti: matrisin satırları t'nin sütunları oldu.
int[][] matris = {{1, 2, 3}, {4, 5, 6}}; int satirSayisi = matris.length; int sutunSayisi = matris[0].length; int[][] t = new int[sutunSayisi][satirSayisi]; for (int i = 0; i < satirSayisi; i++) for (int j = 0; j < sutunSayisi; j++) t[j][i] = matris[i][j];
Matris · Kodu adım adım çalıştır
Matris Çarpımı (2×2)
C[i][j] = A'nın i. satırı ile B'nin j. sütununun çarpımlarının toplamı. C sıfırlarla başlar.
C[0][0] += 1 × 5 → 0 + 5 = 5
C[0][0] += 2 × 7 → 5 + 14 = 19 (hücre tamam)
C[0][1] += 1 × 6 → 0 + 6 = 6
C[0][1] += 2 × 8 → 6 + 16 = 22 (hücre tamam)
C[1][0] += 3 × 5 → 0 + 15 = 15
C[1][0] += 4 × 7 → 15 + 28 = 43 (hücre tamam)
C[1][1] += 3 × 6 → 0 + 18 = 18
C[1][1] += 4 × 8 → 18 + 32 = 50 (hücre tamam)
Üç iç içe döngü: n×n matris için n³ çarpma → O(n³). Sütun sayısı (A) = satır sayısı (B) olmalı.
int[][] A = {{1, 2}, {3, 4}}; int[][] B = {{5, 6}, {7, 8}}; int[][] C = new int[2][2]; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) C[i][j] += A[i][k] * B[k][j];
Tasarım
Dizi mi Liste mi?
- Öğe sayısı baştan belli ve sabitse dizi yeterli ve hızlıdır.
- Öğe sayısı değişecekse
ArrayListgibi koleksiyonlar daha kullanışlıdır. int[]sayıları doğrudan saklar;ArrayList<Integer>her sayıyı bir nesne içinde tutar.- Seçim; kullanım biçimine, okunabilirliğe ve ölçülen performansa göre yapılır.
Doğrulama
Yaygın Hatalar
i <= a.length son turda a[length]'e erişir → ArrayIndexOutOfBoundsException. Doğrusu i < a.length.
int min = a[0]; boş dizide hata verir; önce a.length == 0 kontrolü.
int[] b = a; yeni dizi değildir; b[0] = 9 a'yı da değiştirir. Kopya için a.clone().
Her satırın uzunluğu matris[0].length değildir; iç döngüde matris[i].length kullanılır.
Özet
Bölüm Özeti
Aynı tipte, sabit sayıda öğe; indis 0 … length − 1; değişken diziyi referansla gösterir.
a[i] okuma/yazma sabit sürede; sınır dışı indis çalışma zamanı hatası.
Klasik for (indis gerekince) ve gelişmiş for (döngü değişkenine atama diziyi değiştirmez); toplam, min-max, ters çevirme, arama.
int[][] dizi dizisidir: matris.length satır, matris[i].length sütun sayısı.
Özet
Kontrol Soruları
- Beş öğeli dizinin son indisi nedir?
- Gelişmiş for ne zaman yetersiz kalır?
- Dizi ataması ile öğe kopyası arasındaki fark nedir?
- İkili arama için hangi ön koşul gerekir?
matris.lengthilematris[0].lengthneyi verir?
Cevaplar
- 4 (length − 1).
- İndis gerektiğinde: konumu yazdırmak, hücreye yeni değer yazmak, diziyi tersten veya iki diziyi birlikte gezmek.
- Atama (
b = a) yalnızca referansı kopyalar, iki değişken aynı nesneyi gösterir;clone/Arrays.copyOfyeni bir dizi oluşturur. - Dizinin sıralı olması.
- Satır sayısını ve ilk satırın sütun sayısını.
Özet
Alıştırmalar
- Bir
int[]dizisindeki çift sayıların adedini ve toplamını bulan kodu yazın. - Diziyi ekstra dizi kullanmadan bir konum sağa döndüren (son öğe başa) kodu yazın: {1,2,3,4} → {4,1,2,3}.
- İki sıralı diziyi tek bir sıralı dizide birleştirin (
{1,4,7}+{2,3,9}). - Kabarcık sıralamasına, bir geçişte hiç takas olmazsa erken duran bir
booleanbayrak ekleyin. - Eratosthenes eleğiyle 100'e kadar kaç asal olduğunu sayın (cevap: 25).
- 3×3 bir matrisin ana köşegen toplamını ve transpozunu hesaplayın; matris simetrik mi kontrol edin.
Özet
Kaynaklar
- Deitel ve Deitel, Java: How to Program, Early Objects, 11. baskı, Pearson, 2018.
- Liang, Introduction to Java Programming and Data Structures, 13. baskı, Pearson, 2024.
- Oracle, The Java Tutorials: Arrays.
- Oracle, Java SE 21 API: java.util.Arrays; Java Language Specification SE 21: Bölüm 10, Arrays.
- Sedgewick ve Wayne, Computer Science: An Interdisciplinary Approach, Addison-Wesley, 2016: 1.4 Arrays.
- Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, MIT Press, 2022.