我们正在课堂上学习B树,并被要求在代码中实现它们。老师已经选择了编程语言给我们,我想尝试用C#做。我的问题是以下结构在C#中是非法的,
unsafe struct BtreeNode
{
int key_num; // The number of keys in a node
int[] key; // Array of keys
bool leaf; // Is it a leaf node or not?
BtreeNode*[] c; // Pointers to next nodes
}
具体来说,不允许创建一个指向结构本身的指针。我可以使用一些解决方法或替代方法吗?我很确定在托管代码中必须有一种方法可以做到这一点,但我无法弄明白。
编辑: 埃里克的回答指出了我正确的方向。这是我最终使用的,
class BtreeNode
{
public List<BtreeNode> children; // The child nodes
public static int MinDeg; // The Minimum Degree of the tree
public bool IsLeaf { get; set; } // Is the current node a leaf or not?
public List<int> key; // The list of keys
...
}
答案 0 :(得分:27)
巧合的是,我实际上只是在C#中实现了一个btree,用于个人项目。好玩。我构建了一个按字典顺序排列的可变大小(最多64个字节)键的btree,这带来了许多挑战,特别是在确定存储页面太满或太空时。
我的建议是,刚刚完成这项工作,就是构建一个抽象层,以最抽象的形式捕获btree算法,作为抽象基类。一旦我获得了以该形式捕获的所有btree规则,我就以几种不同的方式对基类进行了专门化:作为常规的固定键大小的2-3 btree,作为我喜欢的可变大小键btree之一,依此类推
首先,在任何情况下你都不应该用指针做这个。不安全的代码很少是必要的,而且从不容易。只有最先进的C#程序员应该关闭安全系统;当你这样做时,你要对程序的类型和内存安全负责。如果你不愿意这样做,请打开安全系统。
其次,没有理由将其作为结构。结构在C#中按值复制; btree节点不是值。
第三,您不需要保留节点中的键数;键数组知道其中有多少键。
第四,我会使用List<T>
而不是数组;他们更灵活。
第五,您需要确定密钥是否存在于节点或父中。无论哪种方式都可以工作;我的偏好是生成在节点中的密钥,因为我看到密钥与节点相关联。
第六,知道btree节点是否是根是有帮助的;你可能会考虑两个bool,一个“这是一片叶子吗?”还有一个“这是根源吗?”当然,其中包含单个项目的btree具有单个节点,即叶子和根。
第七,你可能会把这件事变成可变的;通常一个人不会在C#类上创建公共可变字段。您可以考虑将它们作为属性。此外,子项列表可以增长和缩小,但其身份不会更改,因此请将其作为参考只读:
所以我可能会将我的基本节点构造为:
class Node
{
public int Key { get; set; }
public bool IsRoot { get; set; }
public bool IsLeaf { get; set; }
private List<Node> children = new List<Node>();
public List<Node> Children { get { return this.children; } }
}
有意义吗?
答案 1 :(得分:14)
使用类而不是stuct。扔出指针。
class BtreeNode
{
int key_num; // The number of keys in a node
int[] key; // Array of keys
bool leaf; // Is it a leaf node or not?
BtreeNode[] c; // Pointers to next nodes
}
当你声明一个类类型的变量时,它隐式地是一个引用(非常类似于c中的指针),因为每个类都是一个引用类型。
答案 2 :(得分:8)
所有你需要意识到C中的指针与C#中的引用“有些相似”。 (有各种不同,但为了这个问题的目的你可以专注于相似之处。)两者都允许一个间接层:价值不是数据本身,它是一种达到的方式数据。
上述内容相当于:
class BtreeNode
{
private int keyNumber;
private int[] keys;
private bool leaf;
private BtreeNode[] subNodes;
// Members (constructors etc)
}
(我不太记得B树,但是如果这里的“keys”数组对应于每个子节点的“keyNumber”值,你根本不需要keys
变量。)< / p>