如何表示B树节点?

时间:2012-02-03 17:37:34

标签: c# .net b-tree

我们正在课堂上学习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 
...
}

3 个答案:

答案 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>