我正在使用C#实现B +树。
现在据我所知,树节点应该包含许多(order-1)键,并且指向记录或其他节点的指针数量,即只有叶子节点可以保存实际指向记录的指针,以及内部节点节点会保存指向其他节点的指针。
我对此实现的问题是使用C#generics
Node Class声明为:
class Node< K,V >
{
K [] keys ;
V [] values;
}
现在,当我尝试将节点放入值数组时
_root.Values[0] = left ; // left being of type Node<K,V>
我收到以下错误:
无法将类型'BTree_Library.Node'隐式转换为'V'
所以,我正试图找到解决这个问题的方法,另一个选择是更改实现以保存一个节点数组和一个记录数组。
所以,最后:
在C中我会使用:( void* values; )
我正在寻找与C#相同的东西。
当我们谈论这个主题时,我是否正确理解了B +树结构 参考节点和记录可以互换节点指针?
答案 0 :(得分:3)
您希望叶节点和内部节点采取不同的行为,同时仍然能够将它们都作为节点引用。这描述了一个继承层次结构:
abstract class Node<K, V>
{
public K[] Keys { get; protected set; }
}
class LeafNode<K, V> : Node<K, V>
{
public V[] Values { get; protected set; }
}
class InnerNode<K, V> : Node<K, V>
{
public Node<K, V> Children { get; protected set; }
}
另一种选择是使用void*
的C#等价物,即object
,但这意味着代码不再是类型安全的,并且你必须在任何地方进行转换。我不建议这样做。
话虽如此,为什么要创建自己的B树?它仅在将数据保存在磁盘上而不是在内存中时才有用。如果你只是为了拥有关联数组,那么.Net中的类已经实现了它(比如Dictionary<K,V>
或SortedDictionary<K,V>
)并且完全正常。
答案 1 :(得分:1)
假设正在从班级中执行_root.Values[0] = left
,并且Values
是相当于values
的属性。
如果V始终是Node
的类型,您可以尝试类似
interface INode {
}
class Node<K, V> : INode where V : INode {
}
这将强制V从BTree_Library.Node
派生,这将允许该行编译而没有任何错误。
如果V不总是来自Node
,那么我认为泛型可能是解决这个问题的错误方法。