【发布时间】:2011-04-09 13:58:45
【问题描述】:
我了解trie 背后的概念。但是在实现方面我有点困惑。
我认为构建Trie 类型的最明显方法是让Trie 维护一个内部Dictionary<char, Trie>。事实上,我已经以这种方式编写了一个,并且它有效,但是......这似乎有点矫枉过正。我的印象是 trie 应该是轻量级的,并且为 每个节点 单独设置一个 Dictionary<char, Trie> 对我来说似乎不是很轻量级。
有没有更合适的方法来实现我所缺少的这种结构?
更新:好的!根据 Jon 和 leppie 提供的非常有用的意见,这是我目前的想法:
(1) 我有Trie 类型,它有一个Trie.INodeCollection 类型的私有_nodes 成员。
(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> 对象,直到它们有足够数量的子对象)。然而,它也变得更加复杂。是不是太纠结了?我是否采取了复杂的路线来实现本应直截了当的目标?
【问题讨论】:
标签: .net data-structures dictionary implementation trie