Bölüm 5.3: Trie Veri Yapısı
Çıktı Sorusu · Trie Kavramı
Soru 1: Düğüm ve null Sayısı
ev, evli, eski, es, ekmek kelimeleri 26 öğeli dizi kullanan trie'ye ekleniyor. Trie'yi çizin. Kök dahil kaç düğüm vardır, toplam kaç çocuk referansı null'dır?
Cevabı göster
- Düğümler: e · ev, evl, evli · es, esk, eski · ek, ekm, ekme, ekmek → 11 + kök = 12 (17 karakter).
- Referans: 12 × 26 = 312; dolu olanlar kenar sayısı kadar (11) → 301 null (≈ %96).
- "ev" ve "es" hem kelime hem başka kelimelerin önekidir; bunu yalnızca kelimeSonu işareti gösterir (çift çember).
Adım Adım Çalıştırma · Ekleme
Soru 2: ekle("kara") İzleme
Trie'de "kar" ve "kale" varken ekle("kara") kaç yeni düğüm oluşturur?
Trie'de "kar" ve "kale" var. dugum kökten başlar.
'k' → i = 10; cocuk[10] dolu → yeni düğüm gerekmez, "k" düğümüne ilerlenir (ortak önek).
'a' → i = 0; cocuk[0] dolu → yeni düğüm gerekmez, "ka" düğümüne ilerlenir (ortak önek).
'r' → i = 17; cocuk[17] dolu → yeni düğüm gerekmez, "kar" düğümüne ilerlenir (ortak önek).
'a' → i = 0; cocuk[0] == null → yeni TrieDugumu oluşturulup bağlanır (mavi).
dugum artık "kara" düğümü.
Döngü bitti: kelimeSonu = true (çift çember). Yalnızca 1 yeni düğüm oluşturuldu; "kar" öneki paylaşıldı. O(L).
public void ekle(String kelime) { TrieDugumu dugum = kok; for (char ch : kelime.toCharArray()) { int i = ch - 'a'; if (dugum.cocuk[i] == null) dugum.cocuk[i] = new TrieDugumu(); dugum = dugum.cocuk[i]; } dugum.kelimeSonu = true; }
Çoktan Seçmeli · Ekleme
Soru 3: Önek Olan Kelimeyi Eklemek
Trie'de yalnızca kalem varken ekle("ka") çağrılırsa ne olur?
D: k ve a dalları zaten vardır; döngü yalnızca ilerler ve sonda o düğüm işaretlenir. C yanlıştır: yol vardı ama "ka" kelime değildi; ekledikten sonra ara("ka") true döner. "kalem" etkilenmez.
Çıktı Sorusu · Arama
Soru 4: ara ve onekVarMi
kale, kalem, kar, kara eklenmiş trie'de aşağıdaki kod ne yazdırır?
// trie: kale, kalem, kar, kara
System.out.println(ara("kal"));
System.out.println(onekVarMi("kal"));
System.out.println(ara("kara"));
System.out.println(ara("karar"));
System.out.println(onekVarMi("kx"));Cevabı göster
false true true false false
- "kal": yol var, ama kelimeSonu false → ara false, onekVarMi true.
- "kara": işaretli düğüm → true. "karar": "kara"dan sonra r dalı yok → erken false.
- "kx": k'dan sonra x dalı yok → false.
Çoktan Seçmeli · Arama
Soru 5: Yol Var Ama Kelime Yok
Trie'de and, ant, dad, do var. Aşağıdaki çağrılardan hangisi, aranan yolun tamamı trie'de bulunduğu hâlde false döner?
D: a → n yolu vardır, ama "an" düğümünde kelimeSonu = false; "an" yalnızca and ve ant'ın önekidir. dog ve ab'de dal bulunamaz (do'dan sonra g, a'dan sonra b yok) ve döngü erken false döndürür; dad true döner.
Çoktan Seçmeli · Arama
Soru 6: kelimeSonu Unutulursa
ara metodunun son satırı return dugum.kelimeSonu; yerine return true; yazılırsa metot neye dönüşür?
A: Döngü dal bulamayınca yine false döner, ama yol varsa işarete bakılmadan true döner: bu tam olarak onekVarMi'dir. Trie "da" düğümünü içeriyorsa ara("da") artık yanlışlıkla true verir. C yanlıştır: return false satırı hâlâ çalışır.
Adım Adım Çalıştırma · Otomatik Tamamlama
Soru 7: tamamla("ka") İzleme
Trie'de kar, kale, kalem, kas, at varken tamamla("ka") hangi listeyi döndürür?
Trie: kar, kale, kalem, kas, at. dugumBul("ka") kökten k → a inerek önek düğümünü bulur.
topla("ka"): "ka" kelime değil (kelimeSonu = false); çocuklar indis sırasıyla gezilecek: 'l', 'r', 's'.
topla("kal"): "kal" kelime değil (kelimeSonu = false); çocuklar indis sırasıyla gezilecek: 'e'.
"kale" işaretli → sonuc'a eklenir: sonuc = [kale].
"kalem" işaretli → sonuc'a eklenir: sonuc = [kale, kalem].
"kar" işaretli → sonuc'a eklenir: sonuc = [kale, kalem, kar].
"kas" işaretli → sonuc'a eklenir: sonuc = [kale, kalem, kar, kas].
Tüm çağrılar döndü: tamamla("ka") → [kale, kalem, kar, kas]. "at" hiç ziyaret edilmez; yalnızca önek düğümünün alt ağacı gezilir.
List<String> tamamla(String onek) {
List<String> sonuc = new ArrayList<>();
TrieDugumu d = dugumBul(onek);
if (d != null)
topla(d, new StringBuilder(onek), sonuc);
return sonuc;
}
void topla(TrieDugumu d, StringBuilder yol,
List<String> sonuc) {
if (d.kelimeSonu) sonuc.add(yol.toString());
for (int i = 0; i < 26; i++)
if (d.cocuk[i] != null) {
yol.append((char) ('a' + i));
topla(d.cocuk[i], yol, sonuc);
yol.setLength(yol.length() - 1);
}
}Çıktı Sorusu · Otomatik Tamamlama
Soru 8: tamamla Çıktısı
Kelimeler sırasıyla bal, ba, bas, bat, baba eklenmiş trie'de kod ne yazdırır?
// trie: bal, ba, bas, bat, baba
System.out.println(tamamla("ba"));
System.out.println(tamamla("bx"));
System.out.println(tamamla("bas"));Cevabı göster
[ba, baba, bal, bas, bat] [] [bas]
- topla önce düğümün kendisini ekler ("ba" işaretli), sonra çocukları indis sırasıyla gezer: b (1) < l (11) < s (18) < t (19).
- Ekleme sırası sonucu etkilemez; çıktı her zaman alfabetiktir.
- "bx" düğümü yok → dugumBul null → boş liste.
Adım Adım Çalıştırma · Silme
Soru 9: sil("kalem") İzleme
Trie'de ka, kalem, kas varken sil(kok, "kalem", 0) kaç düğüm siler?
Trie: ka, kalem, kas. sil(kok, "kalem", 0) önce kelimenin sonuna iner; silme kararları dönüşte verilir.
k → a → l → e → m dalları bulunur; her düzeyde sil(c, k, j + 1) çağrılır. Yığında 6 çerçeve var.
j == 5: "kalem" işaretli → kelimeSonu = false; bosMu → çocuğu yok → true (ebeveyn bu düğümü silebilir).
"kale" çocuğunu siler (cocuk[12] = null). "kale" işaretsiz ve artık çocuksuz → true.
"kal" çocuğunu siler (cocuk[4] = null). "kal" işaretsiz ve artık çocuksuz → true.
"ka" düğümü l çocuğunu siler. Ama "ka" bir kelimedir (işaretli) ve s çocuğu var → false: silme burada durur.
Kök false alır, başka değişiklik olmaz. 3 düğüm (m, e, l) silindi; ka ve kas korunur. Kalan: kök + 3 düğüm.
// true: ebeveyn d'yi silebilir boolean sil(TrieDugumu d, String k, int j) { if (j == k.length()) { // kelime bitti if (!d.kelimeSonu) return false; d.kelimeSonu = false; return bosMu(d); // çocuksuz mu? } int i = k.charAt(j) - 'a'; TrieDugumu c = d.cocuk[i]; if (c == null) return false; // kelime yok if (sil(c, k, j + 1)) { d.cocuk[i] = null; // çocuğu sil return !d.kelimeSonu && bosMu(d); } return false; }
Çıktı Sorusu · Silme
Soru 10: Silinen Düğüm Sayıları
Her soruda trie car, card, care, cat kelimeleriyle yeniden kuruluyor. sil("card"), sil("cat") ve sil("ca") kaçar düğüm siler? Trie kol, kola, kolay iken sil("kola") kaç düğüm siler?
Cevabı göster
- sil("card"): d düğümü çocuksuz ve işaretsiz kalır → silinir; "car" işaretli olduğu için durur → 1.
- sil("cat"): t silinir; "ca" işaretsiz ama r çocuğu var → 1.
- sil("ca"): "ca" kelime değil (kelimeSonu false) → hiçbir şey değişmez → 0 (durum 3).
- sil("kola"): yalnızca işaret kalkar; "kola" düğümünün y çocuğu ("kolay") var → 0 (durum 1).
Çoktan Seçmeli · Silme
Soru 11: Hatalı Silme
Bir öğrenci silmeyi "kelimenin yolundaki tüm düğümleri kökten itibaren null yap" diye yazıyor. Trie'de app, apple, apt varken sil("app") çağrılırsa ne olur?
C: Kökten a dalı null yapılınca a ile başlayan her şey (app, apple, apt) kaybolur. Doğru silme yalnızca kelimeSonu'nu kaldırır ve aşağıdan yukarı, çocuksuz ve işaretsiz düğümleri siler; "app"in l çocuğu olduğu için hiçbir düğüm silinmez.
Çoktan Seçmeli · Analiz
Soru 12: Arama Süresi
Bir trie'de n = 1 000 000 kelime var; aranan kelimenin uzunluğu L = 8. ara en kötü durumda kaç düğüm adımı atar?
A: Her karakter için bir çocuğa inilir; kelime sayısı süreyi etkilemez → O(L). D dengeli BST'nin maliyetidir (log n karşılaştırma, her biri O(L)); C düz listede kelime kelime karşılaştırmadır.
Çoktan Seçmeli · Analiz
Soru 13: Trie mi, Hash Tablosu mu?
Bir sözlük uygulamasında aşağıdaki işlemlerden hangisi hash tablosunda verimli yapılamaz, trie'de ise O(P)'de yapılır?
B: "ki" ile "kitap"ın hash değerleri ilişkisizdir; hash tablosu önek sorgusu için tüm tabloyu taramak zorundadır. Trie'de k → i yoluna inmek yeter. Tam kelime ekleme, arama ve silme iki yapıda da O(L) mertebesindedir (hash de L karakteri okur).
Çıktı Sorusu · Analiz
Soru 14: Alfabe Dışı Karakter
26 öğeli diziyle yazılmış dersteki ekle ve ara metotlarıyla bu kod ne yazdırır? Hata oluşursa nedenini açıklayın.
TrieDugumu kok = new TrieDugumu();
ekle("kale");
System.out.println(ara("kale"));
ekle("çay");
System.out.println("bitti");Cevabı göster
true
Ardından program ArrayIndexOutOfBoundsException (indis 134) ile sonlanır.
'ç' Unicode 231'dir: 231 − 97 = 134 ≥ 26 → dugum.cocuk[134] dizi sınırını aşar; "bitti" yazılmaz. Büyük harf de sorundur: 'A' − 'a' = −32.
Çözüm: girdiyi küçük harfe ve a–z alfabesine dönüştürmek ya da çocukları HashMap<Character, TrieDugumu> ile saklamak (her alfabe çalışır).
Çoktan Seçmeli · Analiz
Soru 15: Çocuk Gösterimi Seçimi
Türkçe karakterler (ç, ğ, ı, ö, ş, ü) dahil büyük bir sözlük için düğüm başına belleği küçük tutan ve her alfabeyle çalışan çocuk gösterimi hangisidir?
C: HashMap yalnızca var olan çocuklar kadar yer tutar ve her karakter anahtar olabilir; erişim ortalama O(1). A Türkçe harflerde indis taşmasına yol açar; B her düğüme 65 536 referans ayırır; D ağaç yapısını kurmaya yetmez.
Çıktı Sorusu · Türevler
Soru 16: En Uzun Önek Eşleşmesi
Bir yönlendiricinin ikili trie'sinde rotalar: 1* → A, 10* → B, 101* → C, 0* → D. Adresleri 1001…, 1011…, 0110… ve 1100… ile başlayan paketler hangi rotaya gider?
Cevabı göster
- 1001…: 1 (A) → 10 (B) → 100 düğümü yok → yolda görülen son rota B.
- 1011…: 1 → 10 → 101 (C) → C.
- 0110…: 0 (D) → 01 yok → D.
- 1100…: 1 (A) → 11 yok → A.
Kökten inilirken işaretli (rota) düğümlerin sonuncusu hatırlanır: en uzun önek eşleşmesi O(adres uzunluğu).
Çoktan Seçmeli · Türevler
Soru 17: Sıkıştırılmış Trie
test, toaster, toasting, slow, slowly kelimeleri için standart trie'de kök hariç 19 düğüm vardır. Tek çocuklu ve işaretsiz düğüm zincirleri birleştirilince (sıkıştırılmış trie) kök hariç kaç düğüm kalır?
B: Kalan düğümler: t (iki dal: e, o), test, toast (dal: e, i), toaster, toasting, slow (kelime ve devamı var), slowly → 7. Kenarlar artık alt dizgi taşır ("oast", "ly"). 5 yalnızca kelime sayısıdır; dallanma düğümleri de gerekir.
Klasik Soru · Türevler
Soru 18: En Uzun Ortak Önek
Trie'deki tüm kelimelerin en uzun ortak önekini bulan String enUzunOrtakOnek() metodunu tasarlayın. kalem, kale, kalemlik için sonuç nedir? Karmaşıklık nedir?
Cevabı göster
Kökten inilir; düğümün tek çocuğu varsa ve düğüm bir kelimenin sonu değilse ilerlenir, geçilen karakterler biriktirilir.
String enUzunOrtakOnek() {
StringBuilder s = new StringBuilder();
TrieDugumu d = kok;
while (!d.kelimeSonu && tekCocuk(d) >= 0) {
int i = tekCocuk(d); // yoksa -1
s.append((char) ('a' + i));
d = d.cocuk[i];
}
return s.toString();
}kalem, kale, kalemlik → k-a-l-e tek zincir; "kale" düğümü işaretli → durulur: "kale". İşaret kontrolü olmasaydı zincir dallanmadığı için "kalemlik"e kadar inilirdi; oysa ortak önek, kelimelerden biri olan "kale"den uzun olamaz. Zaman O(P · M) (P: önek uzunluğu, M = 26: tekCocuk her düğümde M hücreyi tarar).