Bölüm 9: Eşlemeler ve
Hash Tabloları
Giriş
Öğrenme Çıktıları
Anahtar-değer ilişkisini ve hash tablosunun temel işleyişini açıklamak.
Zincirleme ve açık adresleme yöntemlerini uygulamak.
Yük faktörü, yeniden boyutlandırma ve dağılım ilişkisini yorumlamak.
Ortalama ve en kötü durum işlem maliyetlerini karşılaştırmak.
Eşleme ve Hash Fikri
Eşleme (Map)
- Veri öğelerini anahtar-değer (key-value) çiftleri olarak saklar.
- Anahtarlar her öğeyi benzersiz (tekil) olarak tanımlar; değerler bu anahtarlarla ilişkilendirilir.
- Değere anahtar üzerinden erişilir: "Ayşe Demir'in telefonu nedir?"
- Hash tablosuyla uygulandığında işlemler ortalama O(1) sürer.
Eşleme ve Hash Fikri
Eşleme ADT'sinin Temel İşlevleri
| İşlev | java.util.Map | Açıklama |
|---|---|---|
| Ekleme (insertion) | put(k, v) | Çifti tabloya ekler |
| Arama (search) | get(k) | k anahtarının değerini döndürür; yoksa null |
| Silme (deletion) | remove(k) | k anahtarlı öğeyi çıkarır, değerini döndürür |
| Güncelleme (update) | put(k, v′) | k zaten varsa değeri v′ ile değiştirir (eskisini döndürür) |
| Diğer | size(), isEmpty(), containsKey(k), keySet(), values() | |
Map<Integer, String> m = new HashMap<>(); m.put(105, "Murat"); m.put(21, "Leyla"); m.put(21, "Ali"); // güncelleme: "Leyla" → "Ali" m.get(21); // "Ali" m.remove(105); // "Murat" m.get(88); // null: böyle bir anahtar yok
Eşleme ve Hash Fikri
Dizi Üzerinde Arama İşlemi
- Dizide arama işleminin zaman karmaşıklığı O(1) yapılabilir mi?
- Öğeleri birbiriyle karşılaştırarak zor: doğrusal arama O(n), sıralı dizide ikili arama O(log n).
- Ama aranan öğenin konumunu (indeksini) biliyorsak erişim tek adımdır:
int[] siraliDizi = {1, 3, 5, 7, 9}; int aranacakIndeks = 2; // erişilmek istenen öğenin indeksi int oge = siraliDizi[aranacakIndeks]; // O(1): oge = 5
Eşleme ve Hash Fikri
İndeksleme: Anahtar = İndeks
Anahtarlar 0–9 arasındaki tam sayılarsa, k anahtarını dizinin k numaralı hücresine koyarız. Arama tek adımdır.
Anahtar uzayındaki her k değeri A[k] hücresine yerleştirilir; kullanılmayan hücreler boş kalır.
ara(3): doğrudan A[3]'e bakılır → dolu → bulundu, O(1).
ara(0): A[0]'a bakılır → boş → bulunamadı, yine O(1).
Eşleme ve Hash Fikri
Doğrudan Adresleme ve Sınırı
- Her olası anahtar için bir hücre ayrılır: arama, ekleme, silme O(1).
- Anahtar uzayı büyükse bellek israfı çok büyüktür: 9 haneli okul numaraları için 109 hücre (int dizisiyle ≈ 4 GB) gerekir, oysa bölümde birkaç yüz öğrenci vardır.
- Anahtar tam sayı değilse ("Ali", "Beyza") doğrudan indeks olarak kullanılamaz.
Eşleme ve Hash Fikri
Hash Tekniği
- Öğe saklama ve erişim amacıyla kullanılan bir tekniktir.
- Öğe için hızlı bir şekilde konum (kova, bucket) bulmak için kullanılır.
- Konum belli ise dizide öğe ekleme, çıkarma ve güncelleme kolaydır.
- Hash tekniği bir hash fonksiyonu kullanır: aldığı anahtarı
0 … N−1aralığında bir tam sayıya (indekse) dönüştürür.
"Ali".hashCode() = 65918 → 65918 mod 13 = 8 (N = 13 kovalı tablo)
Hash Fonksiyonları
Hash Fonksiyonları
- Hash tablosunun temelinde hash fonksiyonu yer alır: anahtarı alır, öğenin tablodaki konumunu (indeksini) üretir.
Kötü fonksiyon
- Her öğe aynı yuvaya hash'lenirse tablo bir bağlı listeye döner: arama O(n).
Kapasite (N) seçimi
- Büyük kapasite belleği israf eder; küçük kapasite çakışmaları artırır.
Hash Fonksiyonları
Hash Kodu + Sıkıştırma
h(k) = |k| mod NN'yi asal seçmek, anahtarlardaki düzenli örüntülerin (10'un katları gibi) aynı kovalara yığılmasını önler.
h(k) = ((a·k + b) mod p) mod Np > N asal; a, b rastgele (a ≠ 0).
| k | k mod 10 | k mod 11 |
|---|---|---|
| 10 | 0 | 10 |
| 20 | 0 | 9 |
| 30 | 0 | 8 |
| 40 | 0 | 7 |
| 50 | 0 | 6 |
N = 10: hepsi aynı kovada. N = 11 (asal): hepsi farklı kovalarda.
Hash Fonksiyonları
Örnek Hash Fonksiyonları
int modulusHash(int anahtar, int diziBoyu) { return anahtar % diziBoyu; }
Tam sayıyı sabit bir sayıya bölüp kalanı döndürür; dizi indeksi hesaplamak için kullanışlıdır.
CRC32long crc32Hash(String anahtar) { CRC32 crc = new CRC32(); // java.util.zip crc.update(anahtar.getBytes()); return crc.getValue(); }
int djb2Hash(String s) { int h = 5381; for (int i = 0; i < s.length(); i++) h = (h * 33) ^ s.charAt(i); return h; }
Klasik DJB2 h*33 + c kullanır; burada XOR'lu biçimi var. Sonuç negatif olabilir, indeks için sıkıştırma gerekir.
// Σ s[i] · 31^(n−1−i) "abc".hashCode() // 96354
97·31² + 98·31 + 99 = 96354
Hash Fonksiyonları
Mod Alma Hash Fonksiyonu: Adım Adım
Boş tablo: uzunluk = 10, indeks = h(anahtar) = anahtar % uzunluk.
h(5) = 5 % 10 = 5 → 5 numaralı yuvaya.
h(1) = 1 % 10 = 1 → 1 numaralı yuvaya.
h(10) = 10 % 10 = 0 → 0 numaralı yuvaya.
h(26) = 26 % 10 = 6 → 6 numaralı yuvaya.
h(99) = 99 % 10 = 9 → 9 numaralı yuvaya. Beş anahtar, beş farklı yuva: çakışma yok.
Hash Fonksiyonları
Çakışmalar (Collisions)
- Farklı anahtarlar aynı indeksi ürettiğinde ortaya çıkar: h(5) = h(105) = 5.
- İki öğe aynı hücrede doğrudan saklanamaz.
- Anahtar uzayı tablodan büyük olduğu için çakışmalar kaçınılmazdır; bir çözüm stratejisi şarttır:
Ayrı Zincirleme
Çakışma Çözümü: Ayrı Zincirleme
h(5) = 5 % 10 = 5 → kova 5 boş; (5, "Ali") düğümü kovaya bağlanır.
h(1) = 1 % 10 = 1 → kova 1 boş; (1, "Tuna") düğümü kovaya bağlanır.
h(10) = 10 % 10 = 0 → kova 0 boş; (10, "Leyla") düğümü kovaya bağlanır.
h(26) = 26 % 10 = 6 → kova 6 boş; (26, "Ceren") düğümü kovaya bağlanır.
h(99) = 99 % 10 = 9 → kova 9 boş; (99, "Sena") düğümü kovaya bağlanır.
h(105) = 105 % 10 = 5 → kova 5 dolu (5, "Ali"): çakışma. Yeni düğüm zincirin başına eklenir.
Ayrı Zincirleme
Hash Tablosu Terminolojisi
Ayrı Zincirleme · Java
Hash Tablosu Uygulaması: Sınıf
public class HashTablosu { private HashDugumu[] kovalar; // zincirlerin ilk düğümleri private int kovaSayisi, buyukluk; public HashTablosu(int kapasite) { this.kovaSayisi = kapasite; this.kovalar = new HashDugumu[kapasite]; this.buyukluk = 0; } private class HashDugumu { private Integer anahtar; private String deger; private HashDugumu sonraki; public HashDugumu(Integer anahtar, String deger) { this.anahtar = anahtar; this.deger = deger; } } }
null; buyukluk = 0.Ayrı Zincirleme · Java
Kova İndeksi: getKovaIndeksi()
// Orijinal: return anahtar % kovalar.length; → anahtar negatifse indeks de negatif! private int getKovaIndeksi(Integer anahtar) { return Math.floorMod(anahtar.hashCode(), kovalar.length); // her zaman 0 … N−1 }
| anahtar | anahtar % 10 | Math.floorMod(anahtar, 10) | Sonuç |
|---|---|---|---|
| 105 | 5 | 5 | kova 5 |
| 21 | 1 | 1 | kova 1 |
| 41 | 1 | 1 | kova 1 (21 ile çakışır) |
| −7 | −7 | 3 | % ile kovalar[-7] → ArrayIndexOutOfBoundsException |
% işleminin sonucu bölünenin işaretini alır. Integer.hashCode() sayının kendisidir; String gibi anahtarlarda hashCode() sıkça negatif olur. Math.abs(h) % N de güvenli değildir: Math.abs(Integer.MIN_VALUE) negatiftir.Ayrı Zincirleme · Java
Anahtar-Değer İkilisi Yerleştirme
public void yerlestir(Integer anahtar, String deger) { int kovaIndeksi = getKovaIndeksi(anahtar); HashDugumu ilk = kovalar[kovaIndeksi]; while (ilk != null) { // anahtar zaten var mı? if (ilk.anahtar.equals(anahtar)) { ilk.deger = deger; // varsa güncelle return; } ilk = ilk.sonraki; } buyukluk++; HashDugumu dugum = new HashDugumu(anahtar, deger); dugum.sonraki = kovalar[kovaIndeksi]; kovalar[kovaIndeksi] = dugum; // zincirin başına }
h(anahtar) ile O(1).Ayrı Zincirleme · Java
Yerleştirme: Adım Adım
HashTablosu tablo = new HashTablosu(10); → 10 boş kova, buyukluk = 0.
h(105) = 105 % 10 = 5 → kova 5 boş (ilk = null) → yeni düğüm eklenir, buyukluk = 1.
h(21) = 21 % 10 = 1 → kova 1 boş → yeni düğüm eklenir, buyukluk = 2.
h(41) = 41 % 10 = 1 → kova 1 dolu: çakışma. Zincir taranır: 21 ≠ 41, sonraki = null → anahtar yok.
Yeni düğüm (41, "Sena") zincirin başına eklenir: 41 → 21. buyukluk = 3.
h(21) = 1 → zincir taranır: ilk düğüm 41 ≠ 21 → ilk = ilk.sonraki.
21 = 21 → anahtar zaten var: değer güncellenir ("Leyla" → "Ali"), return; buyukluk değişmez.
Ayrı Zincirleme · Java
Anahtar ile Değer Getirme
public String getir(Integer anahtar) { int kovaIndeksi = getKovaIndeksi(anahtar); HashDugumu ilk = kovalar[kovaIndeksi]; while (ilk != null) { if (ilk.anahtar.equals(anahtar)) return ilk.deger; // bulundu ilk = ilk.sonraki; } return null; // anahtar yok }
| Çağrı | Kova | İncelenen düğümler | Dönüş |
|---|---|---|---|
tablo.getir(105) | 105 % 10 = 5 | 105 | "Murat" |
tablo.getir(21) | 21 % 10 = 1 | 41, 21 | "Ali" |
tablo.getir(88) | 88 % 10 = 8 | — (kova boş) | null |
Ayrı Zincirleme · Java
Getirme: Adım Adım
Başlangıç: yerleştirmelerden sonraki tablo.
h(105) = 5 → ilk düğüm 105 = 105 → "Murat" döner.
h(21) = 1 → ilk düğüm 41 ≠ 21 → ilk = ilk.sonraki.
İkinci düğüm 21 = 21 → "Ali" döner (2 karşılaştırma).
h(88) = 8 → kova 8 boş, döngüye hiç girilmez → null (anahtar yok).
Ayrı Zincirleme · Java
Hash Tablosundan Anahtar Silme
public String sil(Integer anahtar) { int kovaIndeksi = getKovaIndeksi(anahtar); HashDugumu ilk = kovalar[kovaIndeksi]; HashDugumu onceki = null; while (ilk != null && !ilk.anahtar.equals(anahtar)) { onceki = ilk; ilk = ilk.sonraki; } if (ilk == null) return null; // anahtar yok buyukluk--; if (onceki != null) onceki.sonraki = ilk.sonraki; // ortadan / sondan else kovalar[kovaIndeksi] = ilk.sonraki; // baştan return ilk.deger; }
onceki.sonraki.Ayrı Zincirleme · Java
Silme: Adım Adım
Başlangıç: 3 çift. Sırayla sil(105), sil(88), sil(21), sil(41).
h(105) = 5 → ilk düğüm eşleşti, onceki = null → kovalar[5] = null; "Murat" döner.
h(88) = 8 → kova boş → null döner; buyukluk değişmez.
h(21) = 1 → 41 ≠ 21: onceki = 41, ilk = 21.
21 bulundu, onceki ≠ null → onceki.sonraki = null: 41'in bağı atlanır; "Ali" döner.
h(41) = 1 → ilk düğüm eşleşti → kovalar[1] = null; "Sena" döner. Tablo boş.
Açık Adresleme
Açık Adresleme (Open Addressing)
- Tüm çiftler dizinin kendisinde saklanır; her yuvada en fazla bir çift vardır (bu yüzden n ≤ N).
- Çakışmada bir yoklama dizisi (probe sequence) ile boş yuva aranır:
h(k, i) = (h(k) + f(i)) mod N, i = 0, 1, 2, …
| Yöntem | f(i) | Yoklama dizisi (h(k) = 5, N = 13) | Zayıf yönü |
|---|---|---|---|
| Doğrusal (linear probing) | i | 5, 6, 7, 8, 9, … | Birincil kümelenme |
| Karesel (quadratic probing) | i² | 5, 6, 9, 14→1, 21→8, … | İkincil kümelenme; her yuvayı denemeyebilir |
| Çift hash (double hashing) | i · h₂(k) | 5, 5+d, 5+2d, … (d = h₂(k)) | İkinci fonksiyon hesabı; h₂(k) ≠ 0 olmalı |
Açık Adresleme
Doğrusal Yoklama (Linear Probing)
h(k, i) = (k mod 13 + i) mod 13: dolu yuvaya gelen anahtar bir sonraki yuvaya (gerekirse başa sararak) bakar.
h(18) = 18 mod 13 = 5, h(41) = 41 mod 13 = 2, h(22) = 22 mod 13 = 9 → üçü de ilk denemede boş yuvaya.
h(44) = 44 mod 13 = 5 → denenen: 5, 6 → 44 yuva 6'e (2 yoklama).
h(59) = 59 mod 13 = 7 → yuva 7 boş → 59 yuva 7'e.
h(32) = 32 mod 13 = 6 → denenen: 6, 7, 8 → 32 yuva 8'e (3 yoklama).
h(31) = 31 mod 13 = 5 → denenen: 5, 6, 7, 8, 9, 10 → 31 yuva 10'e (6 yoklama).
h(73) = 73 mod 13 = 8 → denenen: 8, 9, 10, 11 → 73 yuva 11'e (4 yoklama). 5–11 arası tek büyük küme: birincil kümelenme.
Açık Adresleme
Karesel Yoklama (Quadratic Probing)
h(k, i) = (k mod 13 + i²) mod 13: sıçramalar 1, 4, 9, 16… büyür; aynı anahtarlar, farklı yerleşim.
h(18) = 18 mod 13 = 5, h(41) = 41 mod 13 = 2, h(22) = 22 mod 13 = 9 → üçü de ilk denemede boş yuvaya.
h(44) = 44 mod 13 = 5 → denenen: 5, 6 → 44 yuva 6'e (2 yoklama).
h(59) = 59 mod 13 = 7 → yuva 7 boş → 59 yuva 7'e.
h(32) = 32 mod 13 = 6 → denenen: 6, 7, 10 → 32 yuva 10'e (3 yoklama).
h(31) = 31 mod 13 = 5 → denenen: 5, 6, 9, 5+9=14 → 1 → 31 yuva 1'e (4 yoklama).
h(73) = 73 mod 13 = 8 → yuva 8 boş → 73 yuva 8'e.
Açık Adresleme
Çift Hash (Double Hashing)
h(k, i) = (h(k) + i · h₂(k)) mod 13, h₂(k) = 7 − (k mod 7) → adım 1…7 arası, asla 0 değil.
| k | 18 | 41 | 22 | 44 | 59 | 32 | 31 | 73 |
|---|---|---|---|---|---|---|---|---|
| h(k) = k mod 13 | 5 | 2 | 9 | 5 | 7 | 6 | 5 | 8 |
| h₂(k) (çakışmada) | — | — | — | 7−2 = 5 | — | — | 7−3 = 4 | — |
| Denenen yuvalar | 5 | 2 | 9 | 5, 10 | 7 | 6 | 5, 9, 0 | 8 |
Açık Adresleme
Açık Adreslemede Silme: "Silindi" İşareti
Doğrusal yoklama sonrası tablo. 44 silinmek isteniyor.
sil(44): h(44) = 5 → 18 ≠ 44 → yuva 6: 44 bulundu. Yuvayı null yapsak ne olur?
Yanlış yol: yuva 6 boşaltıldı. getir(32): h(32) = 6 → boş yuva → "yok" der. Oysa 32 yuva 8'de!
Doğru yol: yuvaya özel bir silindi işareti (DEFUNCT, tombstone ✗) konur.
getir(32): h = 6 → ✗ silindi, aramaya devam → 7: 59 ≠ 32 → 8: 32 bulundu.
yerlestir(57): h = 5 → 5, 6(✗), 7 … 11 dolu, 12 boş → 57 yok. İlk uygun yuva olan 6'ya yerleşir.
✗ = silindi (DEFUNCT). Arama bu yuvayı dolu gibi atlar; ekleme ise onu boş gibi yeniden kullanabilir.
Açık Adresleme
Yuva Bulma: Arama ve Eklemenin Ortak Adımı
private int yuvaBul(int anahtar) { // Goodrich: findSlot int h = Math.floorMod(anahtar, N), uygun = -1; for (int i = 0; i < N; i++) { int j = (h + i) % N; // doğrusal yoklama if (tablo[j] == null || tablo[j] == SILINDI) { if (uygun == -1) uygun = j; // ilk boş / silindi yuva if (tablo[j] == null) break; // boş yuva: anahtar kesin yok } else if (tablo[j].anahtar == anahtar) return j; // bulundu: indeks ≥ 0 } return -(uygun + 1); // yok: eklenecek yer (negatif kodlu) }
j = yuvaBul(k); j ≥ 0 ise tablo[j].deger, değilse null.tablo[−(j+1)] yuvasına yeni çift.(h + i*i) % NÇift hash:
(h + i*h2) % NTablo hiçbir zaman tamamen dolmaz (λ < 1 tutulur, gerekince büyütülür); bu yüzden uygun her zaman bulunur.
Açık Adresleme
Deneyin: Açık Adresleme (N = 11)
h(k) = k mod 11. Kesikli çerçeve: yoklanan dolu yuva · turuncu: sonuç yuvası · ✗: silindi (DEFUNCT). Enter tuşu = ekle.
Performans ve Uygulamalar
Yük Faktörü (Load Factor)
- λ = n / N (n: çift sayısı = buyukluk, N: kova sayısı).
- Zincirlemede λ, ortalama zincir uzunluğudur; λ > 1 olabilir ama işlemler yavaşlar.
- Açık adreslemede λ ≤ 1 zorunludur; λ → 1 iken yoklama sayısı patlar.
- Pratik eşikler: zincirlemede λ ≈ 0,75 (Java
HashMap), açık adreslemede λ ≤ 0,5. - Tablo yaklaşık %70–75 dolduğunda büyütülür.
| λ | Başarılı | Başarısız |
|---|---|---|
| 0,50 | 1,5 | 2,5 |
| 0,75 | 2,5 | 8,5 |
| 0,90 | 5,5 | 50,5 |
Doğrusal yoklamada beklenen yoklama sayısı (Knuth):
½(1 + 1/(1−λ)) ve ½(1 + 1/(1−λ)²)
Performans ve Uygulamalar
Yeniden Boyutlandırma (Rehashing)
N = 5 kovalı tabloya 12, 7, 20, 33 eklendi. λ = 0,80 eşiği aştı → yeniden boyutlandırma (resizing).
Yeni dizi ayrılır ve her anahtar yeniden hash'lenir (rehashing): indeksler değişir, eski konumlar geçersizdir.
Büyütme tek seferde O(n) sürer ve pahalıdır; ama kapasite her seferinde ~2 katına çıktığından ekleme başına amortize O(1).
Performans ve Uygulamalar
Karmaşıklık Karşılaştırması
| Eşleme uygulaması | getir | yerlestir | sil |
|---|---|---|---|
| Sırasız dizi / liste | O(n) | O(n)* | O(n) |
| Sıralı dizi (ikili arama) | O(log n) | O(n) | O(n) |
| Hash tablosu: ortalama | O(1) | O(1) | O(1) |
| Hash tablosu: en kötü | O(n) | O(n) | O(n) |
* Anahtarın zaten var olup olmadığını kontrol etmek için tüm liste taranır.
Performans ve Uygulamalar
Hash Tablolarının Kullanım Alanları
HashMap, HashSet.Örnek Uygulama
Okul Numarası İçin Hash Fonksiyonu
Numara biçimi: ab070c0de · örnek: 210707003
- ab: kayıt yılı (20–24) · c: bölüm (6 veya 7) · de: kayıt sırası (00–99, iki hane)
- Hedef: bu biçimi 0–999 aralığında bir dizi indeksine dönüştürmek.
Örnek Uygulama
Okul Numarası için Hash Fonksiyonu
| Numara | ab | c | de | Hesap | İndeks |
|---|---|---|---|---|---|
210706003 | 21 | 6 | 03 | (1×100 + 0×500 + 3) mod 1000 | 103 |
240707050 | 24 | 7 | 50 | (4×100 + 1×500 + 50) mod 1000 | 950 |
230707042 | 23 | 7 | 42 | (3×100 + 1×500 + 42) mod 1000 | 842 |
Örnek Uygulama
calculateHash Fonksiyonu
public int calculateHash(String studentId) { // "ab070c0de" int ab = Integer.parseInt(studentId.substring(0, 2)); // ab: kayıt yılı int c = Integer.parseInt(studentId.substring(5, 6)); // c: bölüm int de = Integer.parseInt(studentId.substring(7, 9)); // de: kayıt sırası int yearFactor = (ab - 20) * 100; int departmentFactor = (c - 6) * 500; int hashValue = (yearFactor + departmentFactor + de) % 1000; return hashValue; }
substring(5, 6) yalnızca 5. karakteri (c) verir; substring(7, 9) 7. ve 8. karakterleri (de).calculateHash("240707050")ab = 24, c = 7, de = 50
400 + 500 + 50 = 950
Biçime uymayan girdi (yıl 20–24 dışı, c ∉ {6, 7}) için sonuç çakışabilir ya da negatif olabilir; gerçek kodda girdi doğrulanmalıdır.
Özet
Özet
put, get, remove; aynı anahtarla put = güncelleme.mod N, N asal). Belirleyici, hızlı, düzgün dağılımlı.Özet
Etkileşimli Simülatörler
Özet
Örnek Problemler
- N = 7, h(k) = k mod 7, doğrusal yoklama: 10, 17, 24, 3, 5 sırayla eklenirse son tablo nedir?
- Aynı anahtarları karesel yoklama ile ekleyin.
- Zincirlemeli, N = 10 kovalı bir tabloda 25 çift var. λ nedir? Başarısız bir arama ortalama kaç düğüm inceler?
- Açık adreslemede silinen yuvayı neden doğrudan
nullyapamayız? - 230706015 numarası için hash(ab070c0de) değerini hesaplayın.
- 0, 12, 24, 36 anahtarları N = 12 ve N = 11 ile
k mod Nkullanıldığında hangi kovalara düşer?
Cevapları göster
- 10→3; 17→3,4; 24→3,4,5; 3→3,4,5,6; 5→5,6,0. Tablo: 0:5, 3:10, 4:17, 5:24, 6:3.
- 10→3; 17→3,4; 24→3,4,(3+4=7→0); 3→3,4,0,(3+9=12→5); 5→5,6. Tablo: 0:24, 3:10, 4:17, 5:3, 6:5.
- λ = 25/10 = 2,5; başarısız arama ortalama λ = 2,5 düğüm inceler (tüm zincir taranır).
- Yoklama zinciri kopar: o yuvanın ötesine yerleşmiş anahtarlar "yok" sanılır. Çözüm: "silindi" (DEFUNCT) işareti.
- ab = 23, c = 6, de = 15 → (300 + 0 + 15) mod 1000 = 315.
- N = 12: hepsi 0 (çakışma). N = 11: 0, 1, 2, 3.
Özet
Kaynaklar
- Goodrich, Tamassia ve Goldwasser, Data Structures and Algorithms in Java, 6. baskı, 2014.
- Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, 2022.
- Oracle, Java SE 17
Map,HashMapveHashSetAPI belgeleri.
Son
← → veya boşluk ile gezinin · F: tam ekran · Home/End: ilk/son slayt