У чому різниця між структурами даних trie та radix trie?


96

Чи однакові структури даних trie та radix trie ?

Якщо вони однакові, то що означає радікс трие (AKA Patricia trie)?


4
Хіба я єдиний, кого трохи дратує те, що тег radix-treeшвидше ніж radix-trie? Більше того, є досить багато запитань.
errantlinguist

@errantlinguist Wikipedia називає radix trieстаттю як Radix tree. Більше того, термін "дерево Radix" широко використовується в літературі. Якщо що-небудь, що викликає, спробує "дерева префіксів", для мене це має більше сенсу. Зрештою, всі вони є деревними структурами даних.
Амеліо Васкес-Рейна

Також: "Що означає trix radix (AKA Patricia trie)?" це передбачає, що дерева radix та дерева PATRICIA - це одне і те ж, але це не так (наприклад, див. цю відповідь ). Дерева PATRICIA - це дерева, які ви отримуєте, запустивши алгоритм PATRICIA (також FYI PATRICIA - це абревіатура, що розшифровується як "Практичний алгоритм отримання інформації, закодованої буквено-цифровим"). Отримані дерева можна сприймати як дерева з радіусом radix = 2, що означає, що ви обходите дерево , переглядаючи log2(radix)=1біти вхідного рядка за раз.
Амеліо Васкес-Рейна

Відповіді:


119

Дерево radix - це стисла версія триє. У триє, на кожному краю ви пишете по одній букві, тоді як у дереві PATRICIA (або дереві radix) ви зберігаєте цілі слова.

Тепер припустимо, що у вас є слова hello, hatі have. Щоб зберігати їх у триє , це буде виглядати так:

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

А вам потрібно дев’ять вузлів. Я розмістив літери у вузлах, але насправді вони позначають краї.

У дереві radix ви матимете:

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

і вам потрібно лише п’ять вузлів. На малюнку вище вузли - зірочки.

Отже, в цілому дерево radix займає менше пам'яті , але його важче реалізувати. В іншому випадку варіант використання обох практично однаковий.


Дякую ... Чи можете ви надати мені хороший ресурс для вивчення триє DS ... Це було б дуже
корисно

Я вважаю, що єдиною річчю, яку я використав, коли вперше впровадив Trie, була стаття Вікіпедії . Я не кажу, що він ідеальний, але досить хороший.
Івайло Странджев

1
чи можу я сказати, що пошук у TRIE швидший, ніж дерево Radix? Оскільки в TRIE, якщо ви хочете здійснити пошук наступного символу, вам потрібно побачити i-й індекс у дочірньому масиві поточного вузла, але в дереві radix вам потрібно здійснити пошук усіх дочірніх вузлів послідовно. Див. Код
Спроба

4
Насправді в дереві radix ви не можете мати більше одного ребра, що починається з тієї самої літери, тому ви можете використовувати одне і те ж постійне індексування.
Ivaylo Strandjev

1
@ Випробування алгоритмічно Radix швидше, ніж TRIE, тому варто робити стиснення. Менше вузлів для завантаження і менше місця, як правило, краще. Тим не менш, якість реалізації може відрізнятися.
Гленн Тейтельбаум

68

Моє питання полягає в тому, чи є структура даних Trie і Radix Trie одним і тим же?

Словом, ні. Категорія Radix Trie описує певну категорію Trie , але це не означає, що всі спроби є radix-спробами.

Якщо вони [n't] однакові, то що означає trie Radix (він же Patricia Trie)?

Я припускаю, що Ви мали намір писати - це не Ваше питання, звідси моя виправлення.

Подібним чином PATRICIA позначає конкретний тип trix trix, але не всі спроби radix є спробами PATRICIA.


Що таке триє?

"Trie" описує деревоподібну структуру даних, придатну для використання в якості асоціативного масиву, де гілки або ребра відповідають частинам ключа. Визначення частин тут досить розмите, оскільки різні реалізації спроб використовують різну довжину бітів, щоб відповідати ребрам. Наприклад, двійкове триє має два ребра на вузол, які відповідають 0 або 1, тоді як 16-смугове триє має шістнадцять ребер на вузол, що відповідає чотирьом бітам (або шістнадцяткова цифра: від 0x0 до 0xf).

Ця діаграма, отримана з Вікіпедії, здається, зображує трійку із вставленими (принаймні) клавішами 'A', 'to', 'tea', 'ted', 'ten' та 'inn':

Основна триє

Якби це трие зберігало елементи для клавіш "t", "te", "i" або "in", на кожному вузлі повинна бути присутня додаткова інформація для розрізнення вузлів з нулями та вузлів з фактичними значеннями.


Що таке trix trie?

"Radix trie", схоже, описує форму триє, яка стискає загальні частини префікса, як це описав Івайло Странджев у своїй відповіді. Вважайте, що 256-сторонній огляд, який індексує клавіші "посмішка", "посмішка", "посмішка" та "посмішка", використовуючи такі статичні призначення:

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;

Кожен індекс має доступ до внутрішнього вузла. Це означає, що для отримання smile_itemпотрібно мати доступ до семи вузлів. Вісім звернень до вузлів відповідають smiled_itemі smiles_item, а дев'ять - до smiling_item. Для цих чотирьох елементів усього є чотирнадцять вузлів. Однак усі вони мають перші чотири байти (що відповідають першим чотирьом вузлам). Шляхом конденсації цих чотирьох байт для створення а, rootщо відповідає ['s']['m']['i']['l'], було оптимізовано чотири доступу до вузлів. Це означає менше пам'яті та менше доступу до вузлів, що є дуже хорошим показником. Оптимізацію можна застосовувати рекурсивно, щоб зменшити необхідність доступу до непотрібних байтів суфіксів. Врешті-решт, ви доходите до точки, коли ви лише порівнюєте відмінності між клавішею пошуку та індексованими клавішами в місцях, проіндексованих трие. Це trix trie.

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

Для отримання елементів кожному вузлу потрібна позиція. За допомогою клавіші пошуку "посмішки" та a root.position4 ми отримуємо доступ root["smiles"[4]], що буває root['e']. Ми зберігаємо це у змінній з назвою current. current.positionдорівнює 5, що є місцем різниці між "smiled"і "smiles", тож наступним буде доступ root["smiles"[5]]. Це підводить нас до smiles_itemкінця нашої ланцюжка. Наш пошук завершено, і елемент отримано, маючи лише три звернення до вузла замість восьми.


Що таке трие PATRICIA?

Випробування PATRICIA - це варіант спроб radix, для яких завжди повинні бути лише nвузли, що містять nелементи. У нашому грубо продемонстрували порозрядну TRIE псевдокод вище, є п'яти вузлів в загальній складності : root(який є нульарна вузлом, він не містить фактичне значення), root['e'], root['e']['d'], root['e']['s']і root['i']. У триєрі PATRICIA має бути лише чотири. Давайте подивимося, як ці префікси можуть відрізнятися, розглядаючи їх у двійковому вигляді, оскільки PATRICIA - це двійковий алгоритм.

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 ...

Давайте розглянемо, що вузли додаються у тому порядку, в якому вони представлені вище. smile_itemє коренем цього дерева. Різниця, виділена жирним шрифтом для полегшення виявлення, полягає в останньому байті "smile", в біті 36. До цього моменту всі наші вузли мають однаковий префікс. smiled_nodeналежить в smile_node[0]. Різниця між "smiled"і "smiles"виникає в біті 43, де "smiles"є біт "1", так і smiled_node[1]є smiles_node.

Замість того щоб використовувати в NULLякості філій і / або додаткової внутрішньої інформації для позначення , коли пошук закінчується, гілки зворотного посилання на дерево де - то, тому пошук закінчується , коли зсув для тесту зменшується , а не збільшується. Ось проста діаграма такого дерева (хоча PATRICIA насправді є скоріше циклічним графіком, ніж деревом, як ви побачите), яка була включена до згаданої нижче книги Седжвіка:

Проста діаграма PATRICIA

Можливий більш складний алгоритм PATRICIA, що включає ключі довжини варіанта, хоча деякі технічні властивості PATRICIA втрачаються в процесі (а саме, що будь-який вузол містить загальний префікс із вузлом до нього):

Складна діаграма PATRICIA

Подібне розгалуження дає низку переваг: Кожен вузол містить значення. Це включає корінь. Як наслідок, довжина та складність коду стає набагато коротшою, а насправді дещо швидшою. Щонайменше одна гілка та максимум kгілок (де kкількість бітів у ключі пошуку) слідують, щоб знайти елемент. Вузли крихітні , оскільки в них зберігається лише по дві гілки кожна, що робить їх досить придатними для оптимізації локалізації кешу. Ці властивості роблять PATRICIA моїм улюбленим алгоритмом на сьогоднішній день ...

Я збираюся скоротити цей опис тут, щоб зменшити тяжкість мого насуваючогося артриту, але якщо ви хочете дізнатись більше про PATRICIA, ви можете проконсультуватися з такими книгами, як "Мистецтво комп'ютерного програмування, том 3" Дональда Натта , або будь-який з "Алгоритмів на {your-favorite-language}, частини 1-4" Седжвіка.


Не могли б ви допомогти мені зрозуміти значення терміна "Radix"! Я розумію, як, природним чином, ми можемо спробувати перетворити TRIE на компактну TRIE, дозволивши з’єднати кілька символів / країв в один край. Однак я не можу зрозуміти, чому неущільнений TRIE (просто TRIE) не можна назвати Radix TRIE.
KGhatak

@ Seb - Будемо дуже вдячні за ваш відгук про публікацію stackoverflow.com/questions/40087385/… на дереві Radix. Подяки в adv.
KGhatak

@BuckCherry Я хотів би мати можливість, але, будь ласка, зрозумійте, оскільки мій комп'ютер було вкрадено, я не зміг би докласти зусиль для адекватної відповіді.
аутист

18

TRIE:
Ми можемо мати схему пошуку, де замість порівняння цілого ключа пошуку з усіма існуючими ключами (наприклад, хеш-схеми), ми могли б також порівняти кожен символ ключа пошуку. Слідуючи цій ідеї, ми можемо створити структуру (як показано нижче), яка має три існуючі ключі - „ тато ”, „ даб ” та „ кабіна ”.

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

(cab)   (dab)     (dad)

Це, по суті, M-арне дерево з внутрішнім вузлом, представленим як [*], і листовим вузлом, представленим як []. Ця структура називається трие . Рішення про розгалуження на кожному вузлі може бути рівним кількості унікальних символів алфавіту, скажімо R. Для англійських алфавітів нижнього регістру az, R = 26; для розширених алфавітів ASCII, R = 256, а для двійкових цифр / рядків R = 2.

Компактний TRIE:
Як правило, вузол у триє використовує масив з розміром = R і, таким чином, спричиняє втрату пам'яті, коли кожен вузол має менше країв. Щоб обійти занепокоєння щодо пам’яті, були внесені різні пропозиції. На основі цих варіацій трие також називаються " компактне три " та " стиснене три ". Хоча узгоджена номенклатура зустрічається рідко, найпоширеніша версія компактного тріє формується шляхом групування всіх ребер, коли вузли мають один край. Використовуючи цю концепцію, вищезазначене (рис-I) триє з клавішами "тато", "даб" і "таксі" може мати нижчу форму.

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

Зверніть увагу, що кожен з 'c', 'a' та 'b' є єдиним краєм для відповідного батьківського вузла, а отже, вони конгломеровані в єдиний край "кабіни". Подібним чином, "d" і "a" об'єднані в один край, позначений як "da".

Radix Trie:
Термін radix у математиці означає основу системи числення, і це, по суті, вказує кількість унікальних символів, необхідних для представлення будь-якого числа в цій системі. Наприклад, десяткова система - радікс десять, а двійкова система - радікс два. Використовуючи подібну концепцію, коли ми зацікавлені в характеристиці структури даних або алгоритму за кількістю унікальних символів базової репрезентативної системи, ми позначаємо концепцію терміном «радікс». Наприклад, “radix sort” для певного алгоритму сортування. В одному рядку логіки всі варіанти триечиї характеристики (такі як глибина, потреба в пам'яті, час пропуску / часу виконання і т.д.) залежать від радіуса основних алфавітів, ми можемо назвати їх радіусом «тріє». Наприклад, не-ущільнений, а також ущільнений Trie , коли використання алфавіти аз, ми можемо назвати це Radix 26 синтаксичного дерева . Будь Trie , який використовує тільки два символи (традиційно «0» і «1») можна назвати радікс 2 Trie . Однак якимось чином багато літератур обмежували використання терміна "Radix Trie" лише для ущільненої триє .

Прелюдія до дерева PATRICIA Tree / Trie:
Було б цікаво помітити, що навіть рядки як ключі можуть бути представлені за допомогою двійкових алфавітів. Якщо ми припустимо , кодування ASCII, то ключ «тато» може бути записано в двійковій формі запису двійкового представлення кожного символу в послідовності, скажімо , як « 01100100 01100001 01100100 » шляхом запису двійкових форм «D», «а» і 'd' послідовно. Використовуючи цю концепцію, можна сформувати триє (разом із Radix Two). Нижче ми зобразимо це поняття, використовуючи спрощене припущення, що літери 'a', 'b', 'c' і 'будуть з меншого алфавіту замість ASCII.

Примітка для Рисунку III: Як уже згадувалося, для полегшення зображення, припустимо алфавіт із лише 4 літерами {a, b, c, d} та відповідними двійковими поданнями є «00», «01», «10» та “11” відповідно. Завдяки цьому наші рядкові клавіші „тато”, „даб” та „кабіна” стають „110011”, „110001” та „100001” відповідно. Спроба для цього буде такою, як показано нижче на рис-III (біти зчитуються зліва направо, як і рядки зліва направо).

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

PATRICIA Trie / Tree:
Якщо ми ущільнимо вищезазначене двійкове триє (рис-III), використовуючи ущільнення одного краю, воно мало б набагато менше вузлів, ніж показано вище, і тим не менше, вузли все одно були б більшими, ніж 3, кількість ключів, які він містить . Дональд Р. Моррісон знайшов (у 1968 р.) Інноваційний спосіб використання двійкового триє для зображення N ключів, використовуючи лише N вузлів, і назвав цю структуру даних PATRICIA. Його структура трие по суті позбулася одиночних країв (одностороннє розгалуження); і, роблячи це, він також позбувся поняття двох типів вузлів - внутрішніх вузлів (які не відображають жодного ключа) та листових вузлів (що зображують ключі). На відміну від поясненої вище логіки ущільнення, його трі використовує іншу концепцію, де кожен вузол включає вказівку, скільки бітів ключа потрібно пропустити для прийняття рішення про розгалуження. Ще однією характеристикою його трі PATRICIA є те, що він не зберігає ключі - це означає, що така структура даних не буде придатною для відповіді на запитання, наприклад, перерахування всіх ключів, які відповідають даному префіксу , але це добре для пошуку, якщо ключ існує або не в триє. Тим не менше, термін Patricia Tree або Patricia Trie з тих пір застосовується у багатьох різних, але схожих значеннях, наприклад, для позначення компактного тріє [NIST] або для позначення trix radix із радіусом два [як зазначено в тонкому висловлюванні у WIKI] тощо.

Trie, який може не бути Radix Trie:
Трійковий пошуковий Trie (він же дерево потрійного пошуку), часто скорочений як TST, - це структура даних (запропонована Дж. Бентлі та Р. Седжвіком ), яка виглядає дуже схожою на трійку з тристороннім розгалуженням. Для такого дерева кожен вузол має характерний алфавіт 'x', так що рішення про розгалуження визначається тим, чи є символ ключа меншим, рівним або більшим за 'x'. Завдяки цій фіксованій 3-х напрямковій функції розгалуження, вона забезпечує ефективну пам’ять альтернативу трие, особливо коли R (радікс) дуже великий, наприклад, для алфавітів Unicode. Цікаво, що TST, на відміну від (R-way) trie , не має своїх характеристик, на які впливає R. Наприклад, промах на пошук TST становить ln (N)на відміну від журналу R (N) для R-шляху Trie. Вимоги до пам'яті TST, на відміну від R-way trie , НЕ також є функцією R. Тому ми повинні бути обережними, щоб називати TST радікс-трие. Я, особисто, не думаю, що ми повинні називати це радікс-триє, оскільки жодна (наскільки мені відомо) його характеристика не впливає на радікс, R, його основних алфавітів.


2
Як хтось, хто впровадив PATRICIA згідно з Моррісоном, Седжвіком та Кнутом, я можу сказати вам, що алгоритм, який ви описали тут (який я також намагався описати у своїй відповіді) , все ще дуже підходить для відповіді на запитання, наприклад, перерахувати всі ключі, що відповідають заданому префікс . PS Приємно бачити когось іншого на балу: це інше питання :) Мені подобається це пояснення.
аутист

Re "не підійде для відповіді на запитання, наприклад, перерахувати всі ключі, що відповідають даному префіксу", серйозно?
Pacerier

@Pacerier Звичайно! Класична PATRICIA зберігає ціле число, яке ви можете використовувати як індекс масиву. У масив ви поміщаєте рядок. У триєр ви вводите індекс масиву на основі 0 для рядка. Зробіть функції пошуку та порівняння та вилучення бітів оперованими рядком, що відповідає цілому, а не цілому числу, і якщо ваша функція вставки базується на інших (як і має бути, оскільки там багато повторюваної логіки), і ви ' Буду добре на шляху. Ви також можете використовувати uintptr_tяк ціле число , оскільки, схоже, передбачається, що цей тип існує (хоча і не потрібен).
аутист,

Ви стверджуєте, що "багато літератур обмежують використання терміна" Radix Trie "лише для ущільненого трие." Власне, я не можу знайти жодного іншого посилання, крім wikipedia. Ви знайшли ще когось?
wds

@ wds - Ви можете мати рацію, оскільки я насправді не пам’ятаю, на які ресурси я посилався, коли писав це. Швидке гуглиння отримує мені такі посилання, як mathcs.emory.edu/~cheung/Courses/323/Syllabus/Text/trie02.html або tutorialsdiary.com/radix-trie-patricia-trie-or-compressed-trie, які по суті вказують на або (найімовірніше), отримане з / під впливом wiki. Якщо я знайду будь-який інший надійний / науковий ресурс, я розміщу тут.
KGhatak
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.