C#引用麻烦

发布于 2024-08-21 11:27:31 字数 1776 浏览 3 评论 0原文

我正在大学学习算法课程,对于我的一个项目,我想用 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”关键字。

我做错了什么?

I'm taking an algorithm course at the university, and for one of my projects I want to implement a red-black tree in C# (the implementation itself isn't the project, yet just something i decided to choose to help me out).

My red-black tree should hold string keys, and the object i created for each node looks like this :

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;
    }
}

I already added some basic methods for printing the tree, finding the root, min/max key (by alphabet), etc...

I'm having trouble inserting nodes (hence, building the tree).
Whoever's familiar with red-black trees knows that when adding a node to one side, you could have changed the balance of the tree.
To fix this, you need to "rotate" around nodes on the tree in order to balance the tree out.

I wrote a RightRotate and LeftRotate method in pseudo-code, and then when i tried to implement it in C#, i ran into a bunch of reference problems with the sRbTreeNode object i created.

This is the pseudo-code I wrote for the LeftRotate method :

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

I received a suggestion to implement it straight forward, but without using the 'ref' keyword, which i tried at first.
This is how i did it :

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;
    }

Now, when i debug, i see that it works fine, but the objects i pass to this method are only rotated within the scope of the method. When it leaves this method, it seems like there was no change to the actual nodes. That is why i thought of using the 'ref' keywords in the first place.

What am i doing wrong ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

娇纵 2024-08-28 11:27:31

因为在方法的主体中,您执行以下操作:

root = y;

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

Because in the body of your method you do this:

root = y;

you need to pass root in with a ref modifier. node doesn't need one, becausenode itself is never updated to point at a different ndoe.
.

硬不硬你别怂 2024-08-28 11:27:31

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

您应该能够将其扩展到 C# 而无需太多麻烦 - 除非您使用“ref”关键字,在这种情况下您很可能会得到不可预测的结果。

也许如果您可以显示到目前为止您实际编写的代码,我们可以帮助调试它。

I don't see why you should have had any issues with references - the Left/Right/Parent nodes can be copied just as in this pseudo-code.

You should be able to expand it to C# without too much fuss - unless you're using the 'ref' keyword, in which case you could very well get unpredictable results.

Perhaps if you could show the code you've actually written thus far, and we can help debug that.

可是我不能没有你 2024-08-28 11:27:31

我的建议:

  • 不要包含父指针。它们对于插入或删除算法不是必需的,并且会使您的代码更加复杂。例如,LeftRotate 只需要一个参数即可编写,如果不使用父指针,长度将缩短一半左右。
  • 使用枚举作为Color属性而不是字符串,并在构造函数中对其进行初始化。
  • 如果您还没有阅读本文,请阅读。

My recommendations:

  • Do not include parent pointers. They are not essential for the insertion or deletion algorithms and will make your code more complex. For example LeftRotate can be written with just one parameter and will be about half as long if you do not use parent pointers.
  • Use an enum for the Color property rather than a string, and initialise it in the constructor.
  • Read this article if you haven't already.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文