Menu
Coddy logo textTech

Trie (Önek Ağacı)

Son güncelleme

Bir trie ("tray" olarak okunur) veya önek ağacı, bir dize kümesini karakterlerine göre saklar: her kenar bir karakterle etiketlenir ve kökten bir yol bir öneki heceler. Bir öneki paylaşan kelimeler aynı düğümleri paylaşır, dolayısıyla "car", "card" ve "care" hepsi c-a-r yolunu yeniden kullanır. Kelimelerin bir seferde tek karakter eklenerek yalnızca farklılaştıkları yerde dallandığını görmek için yukarıdaki oynat düğmesine basın.

Aramalar karakter başına bir düğüm gezdiğinden, m uzunluğundaki bir kelimeyi aramak, trie'nin kaç kelime tuttuğundan bağımsız olarak O(m) sürer. Bu, trie'leri otomatik tamamlama, yazım denetimi ve önek araması için ideal kılar.

Zaman ve alan karmaşıklığı

İşlemKarmaşıklıkNotlar
EklemeO(m)m = kelimenin uzunluğu
AramaO(m)Karakter başına bir adım
Önek sorgusuO(m)Önek düğümüne kadar gez
AlanO(total chars)Paylaşılan önekler bir kez saklanır

Adım adım (ekleme)

AdımNe olur
1Kök düğümde başla.
2Kelimedeki her karakter için eşleşen bir çocuk kenarı ara.
3Varsa onu izle (paylaşılan öneki yeniden kullanarak).
4Yoksa o karakter için yeni bir çocuk düğüm oluştur.
5Son karakterden sonra o düğümü kelime sonu olarak işaretle.

Çözümlü örnek

Boş bir trie'ye ["car", "card", "care"] ekleniyor:

AdımYapıİşlem
car ekleroot → c → a → r✓Eşleşen çocuk yok, bu yüzden c, a, r oluştur ve r'yi kelime sonu olarak işaretle.
card ekleroot → c → a → r✓ → d✓Mevcut c-a-r yolunu yeniden kullan, ardından yeni bir d çocuğu oluştur ve kelime sonu olarak işaretle.
care ekleroot → c → a → r✓ → {d✓, e✓}c-a-r'ı yeniden kullan, r'den yeni bir e çocuğuyla dallan ve e'yi kelime sonu olarak işaretle.
care araroot → c → a → r → e✓c, a, r, e boyunca gez; son düğüm kelime sonu olarak işaretli, dolayısıyla care mevcut.
ca araroot → c → aYol var ama a kelime sonu olarak işaretli değil, dolayısıyla ca bir önek ama saklanan bir kelime değil.

Bir trie ne zaman kullanılır

Şu durumda kullanŞu durumda kaçın
Bir dize kümesi üzerinde önek sorguları veya otomatik tamamlamaya ihtiyacın olduğunda.Yalnızca tam anahtar aramalarına ihtiyacın olduğunda - bir karma tablo daha hızlı ve hafiftir.
Saklanan birçok kelime ortak önekler paylaşıp düğümler yeniden kullanıldığında.Anahtarlar uzun ve nadiren örtüştüğünde, karakter başına bir düğüm boşa gider.
Anahtarların bir gezinme ile sıralı olarak döndürülmesini istediğinde.Bellek kısıtlı olduğunda - düğüm başına çocuk işaretçileri önemli ek yük getirir.
Arama maliyeti veri kümesi boyutuna değil anahtar uzunluğuna bağlı olmalıysa.Alfabe çok büyük (örneğin tüm Unicode) ve çocuklar yoğun saklandığında.

Trie (Prefix Tree) kodu

Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir Trie (Prefix Tree) uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.

Python ile Trie (Prefix Tree) kodu

Python
1class TrieNode:2    def __init__(self):3        self.children = {}4        self.is_word = False5
6
7class Trie:8    def __init__(self):9        self.root = TrieNode()10
11    def insert(self, word):12        node = self.root13        for ch in word:14            node = node.children.setdefault(ch, TrieNode())15        node.is_word = True16
17    def search(self, word):18        node = self._walk(word)19        return node is not None and node.is_word20
21    def starts_with(self, prefix):22        return self._walk(prefix) is not None23
24    def _walk(self, s):25        node = self.root26        for ch in s:27            if ch not in node.children:28                return None29            node = node.children[ch]30        return node31
32
33trie = Trie()34for word in ["car", "card", "care", "dog"]:35    trie.insert(word)36
37print("search(card):     ", trie.search("card"))38print("search(ca):       ", trie.search("ca"))39print("starts_with(ca):  ", trie.starts_with("ca"))40print("starts_with(do):  ", trie.starts_with("do"))41print("starts_with(cat): ", trie.starts_with("cat"))
Bu kodu Python Playground'da çalıştır

Trie SSS

Bir trie ne için kullanılır?
Trie'ler önek tabanlı özellikleri güçlendirir: otomatik tamamlama ve arama önerileri, yazım denetleyicileri, IP yönlendirme tabloları ve sözlük aramaları. "Saklanan herhangi bir kelime bu önekle başlıyor mu?" sorgularına hızlı yanıt gerektiren her yerde bir trie parlar.
Bir trie'nin zaman karmaşıklığı nedir?
Ekleme, arama ve önek sorguları, kaç kelimenin saklandığından bağımsız olarak, m kelimenin veya önekin uzunluğu olmak üzere hepsi O(m) sürede çalışır. Ödünleşim bellektir: bir trie çok alan kullanabilir, ancak paylaşılan önekler yalnızca bir kez saklanır.
Bir trie ile karma tablo arasındaki fark nedir?
Bir karma tablo tam anahtarların ortalama O(1) aramasını sunar ancak önek sorgularını yanıtlayamaz. Bir trie arama başına biraz daha yavaştır ama önek araması, sıralı gezinme ve otomatik tamamlamayı doğal olarak destekler - bu durumlarda tercih edilmesinin nedeni budur.
İkili arama ağacı yerine ne zaman trie kullanmalıyım?
Anahtarların dize olduğunda ve önek aramalarına ihtiyacın olduğunda bir trie kullan: anahtar uzunluğu üzerinden işlem başına O(m) çalışır, oysa dengeli bir BST O(m log n) maliyetlidir çünkü her karşılaştırma dizeyi tarar ve bunlardan log n tane vardır. Anahtarlar dize benzeri değilse veya bellek ek yükü önek hızından daha önemliyse BST daha iyi bir seçimdir.
Bir trie'de bir kelimenin sonu nasıl ele alınır?
Her düğüm, yalnızca eklenen tam bir kelime orada bittiğinde ayarlanan bir kelime sonu bayrağı taşır. Bu olmadan, saklanan bir kelimeyi salt bir önekten ayıramazsın - örneğin card ekledikten sonra car düğümü vardır ama yalnızca car da eklendiyse kelime olarak bildirilmelidir.
Trie'ler önekleri paylaşarak her zaman bellek tasarrufu sağlar mı?
Her zaman değil. Paylaşım yalnızca birçok anahtar örtüştüğünde yardımcı olur; uzun, birbirinden farklı anahtarlarla bir trie, bir karma kümeden çok daha fazla bellek kullanabilir, çünkü her karakter çocuk işaretçileriyle kendi düğümü olur. Sorun alansa, sıkıştırılmış bir radix ağacı tek çocuklu zincirleri birleştirerek bu ek yükü azaltır.
Coddy programming languages illustration

Coddy ile algoritmalarda ustalaş

BAŞLA