无法在递归方法中设置对象

时间:2015-06-24 19:29:26

标签: c# recursion methods binary-search-tree

我正在尝试将节点添加到二叉搜索树中。 这里有一个比较两个节点的位置 - 您要添加的节点和树中的节点(第一次是根节点)。

    ...
    Compare(newNode, tree.root);
    ...

    public static void Compare(Node newN, Node comN)
        {
            if (comN == null)
            {
                comN = newN;
                return;
            }
            else
            {
                if (newN.data < comN.data)
                { Compare(newN, comN.left); }
                else if (newN.data > comN.data)
                { Compare(newN, comN.right); }
                else if (newN == comN)
                    return;
            }
        }
        // .data = int value of the node

当我单步执行时:

在“comN = newN;”中部分,节点已设置。然而,在“回归”之后它跳回一个级别,左/右节点(我们之前设置的节点)仍然设置为null。

有什么建议吗? (抱歉可能不正确使用术语,我是新手)

2 个答案:

答案 0 :(得分:3)

由于C#如何传递参数,默认情况下,您正在使用本地参考。将newN设置为Compare(newNode, ref tree.root); ... public static void Compare(Node newN, ref Node comN) { if (comN == null) { comN = newN; return; } else { if (newN.data < comN.data) { Compare(newN, ref comN.left); } else if (newN.data > comN.data) { Compare(newN, ref comN.right); } else if (newN == comN) return; } } 不会复制值:它会设置对同一对象的本地引用,而不会更新调用代码中的引用。您可以通过更改代码来获得预期的行为,如下所示:

{{1}}

有关参考类型和参数的详细信息,请参阅IsEmpty()

答案 1 :(得分:1)

我打算将此课程BST称为Node,而不是data,因为它会让事情变得更加清晰。假设它被定义为接受// C# 6 for brevity class BST { public int Data { get; } public BST Left { get; } public BST Right { get; } public Bst(int data, BST left, BST right) { Data = data; Left = left; Right = right; } } 和左右节点作为参数:

static class BSTExtensions
{
    public static BST Insert(this BST bst, BST n)
    {
        if (bst == null)
            return n;

        if (n.Data < bst.Data)
            return new BST(bst.Data, bst.Left.Insert(n), bst.Right);
        if (n.Data > bst.Data)
            return new BST(bst.Data, bst.Left, bst.Right.Insert(n));

        return bst;
    }
}

您的插入算法可以定义如下:

ref

很容易理解这里发生了什么。

  1. 如果您要比较的节点不存在,则这是新节点应占用的位置。
  2. 如果新节点的值小于当前节点中的值,则插入左子树。
  3. 如果新节点的值大于当前节点的值,请插入右子树。
  4. 如果值相等(唯一剩下的可能性),则不需要进行任何更改。只需返回原始树。
  5. 虽然我也让这个例子中的树变成了不可变的,但如果你在课堂上实现了setter,你可以更高效地完成这项工作,同时仍然不需要N160(8141(30) -- Roughing 1) N33(8141(31) -- Roughing 2)