【问题标题】:C# reference troubleC#参考麻烦
【发布时间】:2011-01-16 03:38:03
【问题描述】:

我正在大学学习算法课程,对于我的一个项目,我想在 C# 中实现一棵红黑树(实现本身不是项目,但我决定选择帮助我出去)。

我的红黑树应该包含字符串键,我为每个节点创建的对象如下所示:

class sRbTreeNode
{
    public sRbTreeNode Parent = null;
    public sRbTreeNode Right = null;
    public sRbTreeNode Left = null;
    public String Color;
    public String Key;

    public sRbTreeNode()
    {
    }

    public sRbTreeNode(String key)
    {
        Key = key;
    }
}

我已经添加了一些用于打印树、查找根、最小/最大键(按字母表)等的基本方法...

我无法插入节点(因此,构建树)。 熟悉红黑树的人都知道,在一侧添加节点时,可能会改变树的平衡。 要解决此问题,您需要围绕树上的节点“旋转”以平衡树。

我用伪代码写了一个 RightRotate 和 LeftRotate 方法,然后当我尝试在 C# 中实现它时,我遇到了一堆我创建的 sRbTreeNode 对象的引用问题。

这是我为 LeftRotate 方法编写的伪代码:

LeftRotate(root, node)
    y <- node.Right;
    node.Right <- y.Left;
    if (y.Left != null)
        y.Left.Parent <- node;
    y.Parent <- node.Parent;
    if (node.Parent = null)
        root <- y;
    else
        if (node = node.Parent.Left)
            node.Parent.Left = y;
        else
            node.Parent.Right = y;
    y.Left <- node;
    node.Parent <- y

我收到了直接实施它的建议,但没有使用我一开始尝试的“ref”关键字。 我就是这样做的:

public static void LeftRotate(sRbTreeNode root, sRbTreeNode node)
    {
        sRbTreeNode y = node.Right;
        node.Right = y.Left;
        if (y.Left != null)
            y.Left.Parent = node;
        y.Parent = node.Parent;
        if (node.Parent == null)
            root = y;
        else
            if (node == node.Parent.Left)
                node.Parent.Left = y;
            else
                node.Parent.Right = y;
        y.Left = node;
        node.Parent = y;
    }

现在,当我调试时,我发现它工作正常,但我传递给此方法的对象仅在方法范围内旋转。当它离开此方法时,实际节点似乎没有任何变化。这就是为什么我首先想到使用“ref”关键字。

我做错了什么?

【问题讨论】:

  • 正如 Andras 所说,向我们展示目前的代码,我们会试一试。

标签: c# algorithm red-black-tree


【解决方案1】:

因为在你的方法体中你这样做:

root = y;

您需要使用ref 修饰符传递rootnode 不需要,因为node 本身永远不会更新为指向不同的 ndoe。 .

【讨论】:

  • 刚刚试了一下,终于成功了!!我不敢相信这很容易,而且我没有意识到!...非常感谢!
【解决方案2】:

我不明白为什么您应该对引用有任何问题 - 可以像在此伪代码中一样复制左/右/父节点。

您应该能够毫不费力地将其扩展为 C# - 除非您使用 'ref' 关键字,在这种情况下,您很可能会得到不可预知的结果。

如果你能展示你到目前为止实际编写的代码,我们可以帮助调试它。

【讨论】:

  • 嗯,我试图使用 ref 关键字,我认为这是正确的方法......我会尝试不使用 ref,看看效果如何,谢谢。
  • 我刚刚用我尝试过的代码编辑了这个问题,也许它会帮助你,因为它不能完全工作,我在上面编辑的问题中解释了原因。
  • 嗯 - 你去 - @AakashM 为你排序!
【解决方案3】:

我的建议:

  • 不包括父指针。它们对于插入或删除算法不是必需的,并且会使您的代码更加复杂。例如,LeftRotate 可以只用一个参数写入,如果不使用父指针,长度大约是原来的一半。
  • Color 属性使用enum 而不是string,并在构造函数中对其进行初始化。
  • 如果您还没有阅读this article,请阅读。

【讨论】:

  • 我需要父指针来获取与结构有关的其他内容。这将使沿着树行进的速度更快。
  • 即使您确实需要它们,在没有它们的情况下先实现算法并稍后添加它们可能会更容易。
猜你喜欢
  • 1970-01-01
  • 2012-07-01
  • 2011-07-26
  • 2011-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
相关资源
最近更新 更多