Подтвердить что ты не робот

Trie экономит место, но как?

Я смущен тем, как реализация Trie сохраняет пространство и сохраняет данные в самой компактной форме!

Если вы посмотрите на дерево ниже. Когда вы храните символ в любом node, вам также нужно сохранить ссылку на него и, следовательно, для каждого символа строки, которую вам нужно сохранить для ссылки. Хорошо, мы сохранили некоторое пространство, когда появился общий символ, но мы потеряли больше места для хранения ссылки на этот символ node.

Значит, нет много структурных издержек, чтобы поддерживать это дерево? Вместо этого, вместо того, чтобы вместо этого использовать TreeMap, можно сказать, что для реализации словаря это могло бы сэкономить намного больше места, поскольку строка будет храниться в одной части, поэтому не нужно тратить время на хранение ссылок, не так ли?

enter image description here

4b9b3361

Ответ 1

Вы можете определить, что это экономит место на идеальной машине, где каждый байт распределяется эффективно. Однако реальные машины выделяют выровненные блоки памяти (8 байтов на Java и 16 байтов на некоторых С++), и поэтому они могут не сохранять какое-либо пространство.

Строки и коллекции Java добавляют относительно высокое количество над головой, поэтому процентная разница может быть очень маленькой.

Если ваша структура не очень велика, ценность ваших временных весов гораздо важнее, чем стоимость памяти, использующая самый простой, самый стандартный и простой в обслуживании сбор. например ваше время может очень легко стоить 1000 или более значений памяти, которую вы пытаетесь сохранить.

например. скажем, у вас 10000 имен, которые вы можете сохранить по 16 байт, используя trie. (Предполагая, что это можно доказать, не затрачивая больше времени) Это соответствует 16 КБ, что в настоящее время цены стоят 0,1 цента. Если ваше время стоит вашей компании в $30 в час, стоимость написания одной строки тестируемого кода может составлять $1.

Если вы задумались над этим, то дольше, чтобы сохранить 16 КБ, его вряд ли стоит того, чтобы он был на ПК. (мобильные устройства - другая история, но тот же аргумент применяется ИМХО)

EDIT: вы вдохновили меня добавить обновление http://vanillajava.blogspot.com/2011/11/ever-decreasing-cost-of-main-memory.html

Ответ 2

Чтобы сэкономить место при использовании trie, можно использовать сжатое trie (также известное как patricia trie или radix tree), для которого один node может представлять несколько символов:

В информатике дерево оснований (также patricia trie или radix trie) представляет собой оптимизированную по пространству структуру данных trie, где каждый node имеет только один ребенок сливается со своим ребенком. В результате каждый внутренний nodeимеет не менее двух детей. В отличие от обычных попыток, края могут быть помечены последовательностями символов, а также одиночными символами. Это делает их намного более эффективными для небольших наборов (особенно, если строки длинны) и для наборов строк, которые имеют длинные префиксы.

Пример дерева оснований:

radix tree or patricia trie

Обратите внимание, что trie обычно используется как эффективная структура данных для сопоставления префикса в наборе строк. Trie также может использоваться как ассоциативный массив (например, хеш-таблица), где ключ представляет собой строку.

Ответ 3

Пространство сохраняется, когда у вас много слов, которые будут представлены деревом. Поскольку многие слова имеют один и тот же путь в дереве; чем больше у вас слов, тем больше места вы сохраните.

Но есть лучшая структура данных, если вы хотите сэкономить место. Trie не экономит место столько, сколько ориентированный ациклический граф слов (DAWG), потому что он имеет общий node по всей структуре, тогда как trie не разделяет узлы. wiki entry объясняет эту деталь, поэтому взгляните на нее.

Вот разница (графически) между Trie и DAWG:

enter image description here

Строки "tap", "taps", "top" и "tops" хранятся в Trie (слева) и DAWG (справа), EOW означает End of-word.

Дерево с левой стороны - Trie, а дерево справа - DAWG. Сравните их и посмотрите, как DAWG экономит пространство. Trie имеет дублированные узлы, которые представляют одно и то же буквенное/подслово, тогда как DAWG имеет ровно один node для каждой буквы/подслова.

Ответ 4

Это не о дешевом пространстве в памяти, о драгоценном пространстве в файле или на линии связи. С помощью алгоритма, который создает этот триггер, мы можем отправить "десять" в три бита, влево-вправо-вправо. По сравнению с 24-битным "десятком" будет занимать несжатые данные, что позволит сэкономить значительное дисковое пространство или пропускную способность.

Ответ 5

Guava действительно может хранить ключ на каждом уровне, но нужно понять, что ключ действительно не нужно хранить, потому что путь к node полностью определяет ключ для этого node. Все, что на самом деле должно храниться в каждом node, является одним логическим, указывающим, является ли это листом node или нет.

Пытается, как и любая другая структура, преуспеть при хранении определенных типов данных. В частности, попытки лучше всего хранить строки, которые имеют общий корень. Подумайте, например, о хранении каталогов списков полного пути.