Я понял концепцию trie .Но я немного запутался, когда дело доходит до реализации.
Самый очевидный способ, которым я мог бы подумать, чтобы структурировать тип Trie
, это иметь Trie
для поддержки внутреннего Dictionary<char, Trie>
.На самом деле я написал один таким образом, и он работает , но ... это кажется излишним.У меня сложилось впечатление, что дерево должно быть легким, и наличие отдельного Dictionary<char, Trie>
для каждого узла не кажется мне очень легким.
Есть ли более подходящий способ реализации этой структурычто мне не хватает?
ОБНОВЛЕНИЕ : ОК!Основываясь на очень полезном вкладе Джона и Леппи, я до сих пор придумал:
(1) У меня есть тип Trie
, который имеет закрытый член типа _nodes
Trie.INodeCollection
.
(2) Интерфейс Trie.INodeCollection
имеет следующие члены:
interface INodeCollection
{
bool TryGetNode(char key, out Trie node);
INodeCollection Add(char key, Trie node);
IEnumerable<Trie> GetNodes();
}
(3) Существует три реализации этого интерфейса:
class SingleNode : INodeCollection
{
internal readonly char _key;
internal readonly Trie _trie;
public SingleNode(char key, Trie trie)
{ /*...*/ }
// Add returns a SmallNodeCollection.
}
class SmallNodeCollection : INodeCollection
{
const int MaximumSize = 8; // ?
internal readonly List<KeyValuePair<char, Trie>> _nodes;
public SmallNodeCollection(SingleNode node, char key, Trie trie)
{ /*...*/ }
// Add adds to the list and returns the current instance until MaximumSize,
// after which point it returns a LargeNodeCollection.
}
class LargeNodeCollection : INodeCollection
{
private readonly Dictionary<char, Trie> _nodes;
public LargeNodeCollection(SmallNodeCollection nodes, char key, Trie trie)
{ /*...*/ }
// Add adds to the dictionary and returns the current instance.
}
(4) Когда Trie
создается впервые, его член _nodes
равен null
.Первый вызов Add
создает SingleNode
, а последующие вызовы Add
идут оттуда в соответствии с шагами, описанными выше.
Имеет ли это смысл?Это похоже на улучшение в том смысле, что несколько уменьшает "громоздкость" Trie
(узлы больше не являются полноценными Dictionary<char, Trie>
объектами до тех пор, пока у них не появится достаточное количество дочерних элементов).Однако, это также стало значительно более сложным.Это слишком запутанно?Должен ли я пойти сложным путем, чтобы достичь чего-то, что должно было быть простым?