Trie ve radix trie veri yapıları arasındaki fark nedir?


99

Are tray ve sayı tabanı tray veri yapıları aynı şey?

Eğer aynı değillerse, o zaman radix trie'nin (AKA Patricia trie) anlamı nedir?


4
Etiketin radix-treedeğil de biraz can sıkıcı bulan tek kişi ben miyim radix-trie? Üstelik onunla etiketlenmiş epeyce soru var.
errantlinguist

1
@errantlinguist Wikipedia radix triemakaleyi olarak adlandırıyor Radix tree. Ayrıca "Radix ağacı" terimi literatürde yaygın olarak kullanılmaktadır. Eğer arayan bir şey "önek ağaçları" denerse bana daha mantıklı gelir. Sonuçta, hepsi ağaç veri yapılarıdır.
Amelio Vazquez-Reina

1
Ayrıca: "Radix trie'nin (AKA Patricia trie) anlamı nedir?" bu, radix ağaçları ve PATRICIA ağaçlarının bir ve aynı şey olduğunu varsayar, ancak bunlar değildir (örneğin, bu yanıta bakın ). PATRICIA ağaçları, PATRICIA algoritmasını çalıştırarak elde ettiğiniz ağaçlardır (ayrıca FYI PATRICIA, "Alfanümerik Olarak Kodlanmış Bilgileri Almak İçin Pratik Algoritma" anlamına gelen bir kısaltmadır). Ortaya çıkan ağaçlar , bir kerede girdi dizgisinin bitlerine bakarak ağaçtanradix = 2 geçtiğiniz anlamına gelen radix ağaçları olarak anlaşılabilir . log2(radix)=1
Amelio Vazquez-Reina

Yanıtlar:


126

Bir taban ağacı, bir trie'nin sıkıştırılmış bir versiyonudur. Bir üçlüde, her bir kenara tek bir harf yazarken, bir PATRICIA ağacında (veya taban ağacında) tüm kelimeleri saklarsınız.

Şimdi, kelimeleri varsayalım hello, hatve have. Onları bir üçlüde saklamak şöyle görünür:

    e - l - l - o
  /
h - a - t
      \
       v - e

Ve dokuz düğüme ihtiyacınız var. Harfleri düğümlere yerleştirdim ama aslında kenarları etiketliyorlar.

Bir radix ağacında sahip olacaksınız:

            *
           /
        (ello)
         /
* - h - * -(a) - * - (t) - *
                 \
                 (ve)
                   \
                    *

ve yalnızca beş düğüme ihtiyacınız var. Yukarıdaki resimde, düğümler yıldız işaretidir.

Bu nedenle, genel olarak, bir radix ağacı daha az bellek alır , ancak uygulaması daha zordur. Aksi takdirde her ikisinin de kullanım durumu hemen hemen aynıdır.


Teşekkürler ... Trie DS'yi incelemek için bana iyi bir kaynak sağlayabilir misiniz ... Bu çok yardımcı olur ...
Aryak Sengupta

Trie'yi ilk uyguladığımda kullandığım tek şeyin wikipedia makalesi olduğuna inanıyorum . Mükemmel olduğunu söylemiyorum ama yeterince iyi.
Ivaylo Strandjev

1
TRIE'de aramanın Radix ağacından daha hızlı olduğunu söyleyebilir miyim? Çünkü TRIE'de bir sonraki karakteri aramak isterseniz, geçerli düğümün alt dizisindeki ith dizini görmeniz gerekir, ancak radix ağacında sırayla tüm alt düğümleri aramanız gerekir. Uygulama koduna
deneniyor

4
Aslında bir taban ağacında aynı harfle başlayan birden fazla kenara sahip olamazsınız, böylece aynı sabit indekslemeyi kullanabilirsiniz.
Ivaylo Strandjev

1
@ Algoritmik Radix'i denemek TRIE'den daha hızlıdır, bu yüzden sıkıştırmaya değer. Yüklenecek daha az düğüm ve daha az alan genellikle daha iyidir. Bununla birlikte, uygulama kalitesi değişebilir.
Glenn Teitelbaum

70

Sorum şu: Trie veri yapısı ve Radix Trie aynı şey mi?

Kısacası hayır. Kategori Radix Trie belli bir kategorisini tanımlamaktadır Trie , ama hepsi çalışır sayı tabanı çalışır anlamına gelmez.

Aynı [n değil], o zaman Radix trie'nin anlamı nedir?

Sana yazma anlamına varsayalım değildir benim düzeltme dolayısıyla sorunuzu.

Benzer şekilde, PATRICIA belirli bir radix tri tipini belirtir, ancak tüm radix denemeleri PATRICIA denemeleri değildir.


Trie nedir?

"Trie", dalların veya kenarların bir anahtarın parçalarına karşılık geldiği bir ilişkilendirilebilir dizi olarak kullanıma uygun bir ağaç veri yapısını açıklar . Parçaların tanımı burada oldukça belirsizdir, çünkü farklı deneme uygulamaları kenarlara karşılık gelmek için farklı bit uzunlukları kullanır. Örneğin, bir ikili üçlü, düğüm başına 0 veya 1'e karşılık gelen iki kenara sahipken, 16 yollu bir üçlü, dört bit'e karşılık gelen düğüm başına on altı kenara (veya bir onaltılık sayı: 0x0'dan 0xf'ye) sahiptir.

Wikipedia'dan alınan bu diyagram, (en azından) 'A', 'to', 'tea', 'ted', 'on' ve 'inn' tuşlarının takılı olduğu bir trie tasvir ediyor gibi görünüyor:

Temel üçlü

Bu triye 't', 'te', 'i' veya 'in' anahtarları için öğeleri depolayacak olsaydı, düğüm düğümleri ve gerçek değerlere sahip düğümler arasında ayrım yapmak için her düğümde ekstra bilgi olması gerekirdi.


Radix trie nedir?

Ivaylo Strandjev'in cevabında tanımladığı gibi, "Radix trie", ortak önek parçalarını yoğunlaştıran bir triye biçimini tanımlıyor gibi görünüyor. Aşağıdaki statik atamaları kullanarak "gülümsemek", "gülümsemek", "gülümsemek" ve "gülümsemek" tuşlarını indeksleyen 256 yönlü bir üçlü olduğunu düşünün:

root['s']['m']['i']['l']['e']['\0'] = smile_item;
root['s']['m']['i']['l']['e']['d']['\0'] = smiled_item;
root['s']['m']['i']['l']['e']['s']['\0'] = smiles_item;
root['s']['m']['i']['l']['i']['n']['g']['\0'] = smiling_item;

Her alt simge dahili bir düğüme erişir. Bu, geri almak için smile_itemyedi düğüme erişmeniz gerektiği anlamına gelir . Sekiz düğüm karşılık erişir smiled_itemve smiles_itemve dokuz smiling_item. Bu dört öğe için toplamda on dört düğüm vardır. Ancak hepsinde ortak olan ilk dört bayta (ilk dört düğüme karşılık gelir) sahiptir. rootKarşılık gelen a oluşturmak için bu dört baytı yoğunlaştırarak ['s']['m']['i']['l'], dört düğüm erişimi optimize edilmiştir. Bu, daha az bellek ve daha az düğüm erişimi anlamına gelir ki bu çok iyi bir göstergedir. Optimizasyon, gereksiz sonek baytlarına erişme ihtiyacını azaltmak için yinelemeli olarak uygulanabilir. Sonunda, trie tarafından dizine eklenen konumlarda yalnızca arama anahtarı ile dizine alınmış anahtarlar arasındaki farkları karşılaştırdığınız bir noktaya gelirsiniz. Bu bir taban tablasıdır.

root = smil_dummy;
root['e'] = smile_item;
root['e']['d'] = smiled_item;
root['e']['s'] = smiles_item;
root['i'] = smiling_item;

Öğeleri geri almak için her düğümün bir konuma ihtiyacı vardır. Bir arama "gülümsüyor" nin anahtar ve bir ile root.position4, biz erişimine root["smiles"[4]]olur, root['e']. Bunu adlı bir değişkende saklarız current. current.position5, "smiled"ve arasındaki farkın konumu "smiles", dolayısıyla bir sonraki erişim olacaktır root["smiles"[5]]. Bu bizi smiles_itemve dizimizin sonuna getiriyor . Aramamız sona erdi ve öğe, sekiz yerine sadece üç düğüm erişimi ile geri alındı.


PATRICIA üçlüsü nedir?

PATRICIA üçlüsü, yalnızca öğeleri niçeren düğümlerin kullanılması gereken bir radix denemeleri varyantıdır n. Yukarıdaki kabaca göstermiştir kök tray pseudocode, toplam beş düğümleri vardır: root(a nullary düğümü, bu yüzden bu gerçek bir değer içerir), root['e'], root['e']['d'], root['e']['s']ve root['i']. PATRICIA üçlüsünde sadece dört tane olmalıdır. PATRICIA ikili bir algoritma olduğu için, bu öneklerin ikili olarak bakarak nasıl farklılık gösterebileceğine bir göz atalım.

smile:   0111 0011  0110 1101  0110 1001  0110 1100  0110 0101  0000 0000  0000 0000
smiled:  0111 0011  0110 1101  0110 1001  0110 1100  0110 0101  0110 0100  0000 0000
smiles:  0111 0011  0110 1101  0110 1001  0110 1100  0110 0101  0111 0011  0000 0000
smiling: 0111 0011  0110 1101  0110 1001  0110 1100  0110 1001  0110 1110  0110 0111 ...

Düğümlerin yukarıda verildikleri sırayla eklendiğini düşünelim. smile_itembu ağacın köküdür. Tespit etmeyi biraz kolaylaştırmak için kalınlaştırılan fark, "smile"36 bitinin son baytındadır. Bu noktaya kadar, tüm düğümlerimiz aynı öneke sahiptir. smiled_nodeait smile_node[0]. Arasındaki fark "smiled"ve "smiles"bit 43, meydana gelir "smiles", böylece bir '1' bit olan smiled_node[1]bir smiles_node.

Aksine kullanmaktan daha NULLbir arama sonlandırıldığında, dalları geri bağlantı zaman şube ve / veya göstermek için ekstra iç bilgi olarak yukarı ağaç yerde testine ofset arama sonlandırıldığında, böylece azalır ziyade artar. İşte böyle bir ağacın basit bir diyagramı ( göreceğiniz gibi PATRICIA aslında bir ağaçtan çok döngüsel bir grafiktir), Sedgewick'in aşağıda bahsedilen kitabına dahil edilmiştir:

Basit PATRICIA diyagramı

PATRICIA'nın bazı teknik özelliklerinin süreçte kaybolmasına rağmen (yani, herhangi bir düğüm, önündeki düğümle ortak bir önek içerir), değişken uzunluktaki anahtarları içeren daha karmaşık bir PATRICIA algoritması mümkündür:

Karmaşık PATRICIA diyagramı

Bu şekilde dallanmanın birçok faydası vardır: Her düğüm bir değer içerir. Bu kökü içerir. Sonuç olarak, kodun uzunluğu ve karmaşıklığı çok daha kısalır ve gerçekte muhtemelen biraz daha hızlı hale gelir. Bir öğeyi bulmak için en az bir dal ve en çok kdal (burada karama anahtarındaki bit sayısı) izlenir. Düğümler küçüktür , çünkü her biri yalnızca iki dal depolarlar, bu da onları önbellek yerelliği optimizasyonu için oldukça uygun kılar. Bu özellikler PATRICIA'yı şimdiye kadarki favori algoritmam yapıyor ...

Yaklaşan artritimin ciddiyetini azaltmak için bu açıklamayı burada kısaltacağım, ancak PATRICIA hakkında daha fazla bilgi edinmek isterseniz Donald Knuth'un "The Art of Computer Programming, Volume 3" gibi kitaplara başvurabilirsiniz. veya Sedgewick tarafından yazılan "{your-favorite-language}, 1-4 bölümlerindeki Algoritmalar" dan herhangi biri.


"Radix" teriminin anlamını anlamama yardım eder misiniz? Birden fazla sembolün / kenarın bir kenarda birleşmesine izin vererek bir TRIE'yi nasıl kompakt bir TRIE'ye dönüştürmeye çalışabileceğimizi anlıyorum. Bununla birlikte, sıkıştırılmamış bir TRIE'nin (sadece bir TRIE) Radix TRIE olarak adlandırılamayacağını anlayamıyorum.
KGhatak

@ Seb - Radix Tree'deki stackoverflow.com/questions/40087385/… postasındaki geri bildiriminizi gerçekten takdir ediyorum . Thnks in adv.
KGhatak

@BuckCherry Yapabilmeyi çok isterdim, ancak lütfen bilgisayarım çalındığı için çabayı yeterli bir yanıt için harcayamayacağımı fark et.
otistik

19

TRIE:
Bütün bir arama anahtarını tüm mevcut anahtarlarla (bir karma düzeni gibi) karşılaştırmak yerine, arama anahtarının her karakterini de karşılaştırabileceğimiz bir arama şemasına sahip olabiliriz. Bu fikrin ardından, mevcut üç anahtarı olan bir yapı (aşağıda gösterildiği gibi) oluşturabiliriz - " baba ", " dab " ve " kabin ".

         [root]
     ...// | \\...
           |  \
           c   d
           |    \
          [*]    [*]
      ...//|\.  ./|\\...        Fig-I
        a       a
       /       /
     [*]      [*]
 ...//|\..  ../|\\...
    /        /   \
   B        b     d
  /        /       \
 []       []       []

(cab)   (dab)     (dad)

Bu, esasen [*] ile temsil edilen iç düğümü ve [] ile temsil edilen yaprak düğümü olan bir M-ary ağacıdır. Bu yapıya trie denir . Her düğümdeki dallanma kararı, alfabenin benzersiz sembollerinin sayısına eşit tutulabilir, örneğin R. Küçük harf İngiliz alfabeleri için az, R = 26; genişletilmiş ASCII alfabeleri için, R = 256 ve ikili rakamlar / dizeler için R = 2.

Kompakt TRIE:
Tipik haliyle, bir bir düğüm tray boyutu = R, bir dizi kullanır ve böylece her bir düğüm az kenarlara sahip olduğu zaman hafıza kaybına neden olmaktadır. Hafıza endişesini aşmak için çeşitli önerilerde bulunuldu. Bu varyasyonlara dayanarak trie , " kompakt üçlü " ve " sıkıştırılmış trie " olarak da adlandırılır . Tutarlı bir isimlendirme nadir olmakla birlikte, bir kompakt trie'nin en yaygın versiyonu, düğümler tek kenara sahip olduğunda tüm kenarların gruplanmasıyla oluşturulur. Bu konsepti kullanarak, yukarıdaki (Şekil-I) “baba”, “dab” ve ”kabin” tuşlarının bulunduğu üçlü aşağıdaki formu alabilir.

         [root]
     ...// | \\...
           |  \
          cab  da
           |    \
          [ ]   [*]                Fig-II
               ./|\\...
                 |  \
                 b   d
                 |    \
                []    []

'C', 'a' ve 'b'nin her birinin, karşılık gelen ebeveyn düğümü için tek kenar olduğunu ve bu nedenle, tek bir kenar "kabin" içinde toplandığını unutmayın. Benzer şekilde, "d" ve a "," da "olarak etiketlenen tek kenarda birleştirilir.

Radix Trie: Matematikte radix
terimi , bir sayı sisteminin tabanı anlamına gelir ve esasen o sistemdeki herhangi bir sayıyı temsil etmek için gereken benzersiz sembollerin sayısını gösterir. Örneğin, ondalık sistem radix on ve ikili sistem radix 2'dir. Benzer kavramı kullanarak, bir veri yapısını veya bir algoritmayı, temelde yatan temsil sisteminin benzersiz sembollerinin sayısına göre karakterize etmekle ilgilendiğimizde, kavramı "radix" terimiyle etiketleriz. Örneğin, belirli bir sıralama algoritması için "taban sıralaması". Aynı mantık çizgisinde, trie'nin tüm varyantlarıözellikleri (derinlik, bellek ihtiyacı, arama kaçırma / vurma çalışma süresi, vb.) temeldeki alfabelerin tabanına bağlı olanlara, bunlara radix “trie” diyebiliriz. Örneğin, sıkıştırılmamış ve sıkıştırılmış bir üçlü , harf harflerini az kullandığında, buna radix 26 üçlüsü diyebiliriz . Yalnızca iki sembol (geleneksel olarak '0' ve '1') kullanan herhangi bir üçlü, radix 2 üçlüsü olarak adlandırılabilir . Bununla birlikte, bir şekilde birçok literatür, "Radix Trie" teriminin kullanımını yalnızca sıkıştırılmış trie için kısıtladı .

PATRICIA Tree / Trie'ye Giriş:
Anahtarlar olarak dizelerin bile ikili alfabeler kullanılarak temsil edilebileceğini fark etmek ilginç olacaktır. ASCII kodlamasını varsayarsak, bir anahtar "baba", her karakterin ikili gösterimini sırayla yazarak ikili biçimde yazılabilir , örneğin " 01100100 01100001 01100100 " olarak "d", "a" ikili biçimlerini yazarak ve Sırayla 'd'. Bu kavramı kullanarak bir trie (Radix Two ile) oluşturulabilir. Aşağıda bu kavramı, 'a', 'b', 'c' ve 'harflerinin ASCII yerine daha küçük bir alfabeden geldiğine dair basitleştirilmiş bir varsayım kullanarak tasvir ediyoruz.

Şekil-III için not: Belirtildiği gibi, tasviri kolaylaştırmak için, sadece 4 harfli {a, b, c, d} bir alfabe varsayalım ve bunlara karşılık gelen ikili gösterimler "00", "01", "10" ve Sırasıyla "11". Bununla birlikte, "dad", "dab" ve "cab" dize anahtarlarımız sırasıyla "110011", "110001" ve "100001" olur. Bunun için trie, aşağıda Şekil III'te gösterildiği gibi olacaktır (bitler, tıpkı dizelerin soldan sağa doğru okunduğu gibi soldan sağa okunur).

          [root]
             \1               
              \
              [*]
             0/ \1               
             /   \
           [*]   [*]         
           0/     /               
           /     /0
         [*]    [*]      
        0/      /               
        /      /0
      [*]    [*]
     0/     0/ \1                Fig-III
     /      /   \
    [*]   [*]   [*]
     \1     \1    \1
      \      \     \
      []     []    []
    (cab)   (dab) (dad)

PATRICIA Trie / Tree:
Yukarıdaki ikili trie'yi (Şekil III) tek kenarlı sıkıştırmayı kullanarak sıkıştırırsak, yukarıda gösterilenden çok daha az düğüme sahip olur ve yine de düğümler, içerdiği anahtar sayısı olan 3'ten daha fazla olacaktır. . Donald R. Morrison , yalnızca N düğümlerini kullanarak N anahtarları tasvir etmek için ikili trie'yi kullanmanın yenilikçi bir yolunu buldu (1968'de) ve bu veri yapısını PATRICIA olarak adlandırdı.. Onun üçlü yapısı esasen tek kenarlardan kurtuldu (tek yönlü dallanma); ve bunu yaparken, iki tür düğüm kavramından da kurtuldu - iç düğümler (herhangi bir anahtarı tasvir etmeyen) ve yaprak düğümler (anahtarları tasvir eden). Yukarıda açıklanan sıkıştırma mantığından farklı olarak, onun trie'si, her bir düğümün dallanma kararı vermek için bir anahtarın kaç bitinin atlanacağına dair bir gösterge içerdiği farklı bir konsept kullanır. PATRICIA denemesinin bir başka özelliği de anahtarları saklamamasıdır - bu, bu tür veri yapısının belirli bir önekle eşleşen tüm anahtarları listeleme gibi soruları yanıtlamak için uygun olmayacağı , ancak bir anahtarın var olup olmadığını bulmak için iyi olacağı anlamına gelir. üçlüde değil. Bununla birlikte, Patricia Tree veya Patricia Trie terimi, o zamandan beri, pek çok farklı ama benzer anlamda kullanılmıştır, örneğin, kompakt bir üçlüsü [NIST] belirtmek için veya taban tabanı iki [bir ince olarak belirtildiği gibi) WIKI'de yol] vb.

Bir Radix Trie olmayabilir Trie:
Üçlü Arama Trie (diğer adıyla Üçlü Arama Ağacı), genellikle TST olarak kısaltılır ( J. Bentley ve R. Sedgewick tarafından önerilen ), üç yollu dallara sahip bir trie'ye çok benzeyen bir veri yapısıdır . Böyle bir ağaç için, her düğümün karakteristik bir "x" alfabesi vardır, böylece dallanma kararı, bir anahtarın karakterinin "x" den küçük, ona eşit veya büyük olup olmadığına göre belirlenir. Bu sabit 3 yollu dallanma özelliği sayesinde, özellikle R (taban) Unicode alfabeleri gibi çok büyük olduğunda, trie için bellek açısından verimli bir alternatif sağlar. İlginç bir şekilde, TST, (R-yolu) trie'den farklı olarak , R'den etkilenen özelliklerine sahip değildir. Örneğin, TST için arama kaçırma ln (N) 'dir.zıt olarak günlük R (K) R 'yönlü tray için. TDT Bellek gereksinimleri, aksine R yönlü tray olduğu DEĞİL yanı R bir fonksiyon. Bu yüzden bir TST'ye radix-trie demeye dikkat etmeliyiz. Ben şahsen, ona taban tabanı dememiz gerektiğini düşünmüyorum, çünkü özelliklerinin hiçbiri (bildiğim kadarıyla) onun temelindeki alfabelerin radixinden (R) etkilenmiyor.


2
PATRICIA'yı Morrison, Sedgewick ve Knuth'a göre uygulayan biri olarak, burada tanımladığınız algoritmanın (cevabımda da açıklamaya çalıştığım) , verilen bir anahtarla eşleşen tüm anahtarları listeleme gibi soruları yanıtlamak için hala çok uygun olduğunu söyleyebilirim. önek . Not: Topun üzerinde başka birini görmek harika: diğer soru :) Bu açıklamayı beğendim.
otistik

"Belirli bir önekle eşleşen tüm anahtarları listelemek gibi soruları yanıtlamak için uygun olmayacak" cidden?
Pacerier

@Pacerier Tabii! Klasik PATRICIA, bir dizi için dizin olarak kullanabileceğiniz bir tamsayı saklar. Diziye dizeyi koyarsınız. Üçlüye, dizge için 0 tabanlı dizi indeksini koyarsınız. Arama & karşılaştırma & bit çıkarma işlevlerinin tamsayı yerine tamsayıya karşılık gelen dizge üzerinde çalışmasını sağlayın ve eğer ekleme işleviniz diğerlerine dayanıyorsa (olması gerektiği gibi, çünkü orada çok sayıda tekrarlanan mantık vardır) ve siz ' Yolunda iyi olacağım. Ayrıca kullanabilirsiniz uintptr_tsenin kadar tamsayı o türü genellikle varolmaya (gerekli olmasa da) beklenen gibi görünüyor, çünkü.
otistik

"Pek çok literatür," Radix Trie "teriminin kullanımını yalnızca sıkıştırılmış üçlü için kısıtladı" diyorsunuz. Aslında wikipedia'dan başka bir referans bulamıyorum. Başkalarını buldun mu?
wds

@ wds - Haklı olabilirsin, çünkü bunu yazarken bahsettiğim kaynakların ne olduğunu gerçekten hatırlamıyorum. Hızlı bir googling, bana mathcs.emory.edu/~cheung/Courses/323/Syllabus/Text/trie02.html veya tutorialsdiary.com/radix-trie-patricia-trie-or-compressed-trie gibi temelde veya (büyük olasılıkla) wiki'den türetilmiş / etkilenmiştir. Başka güvenilir / bilimsel kaynak bulursam, buraya göndereceğim.
KGhatak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.