0

考虑我有对象 A,它持有对 B 对象类型的引用,但这次初始化为 null。

A->B( == null)

我想将 null 替换为 B 类型的对象,该对象持有对 C 类型的引用
(B->C)
所以我会得到A->B->C

为什么不能通过提供 B 对象的引用来链接它们(它持有 null 但可能链接到幕后的特定内存地址并分配给它 C 对象而不是 null 所以之后它将是 A->B- >C?

为什么我必须转发 A 对象才能进行此操作?

这个问题是为了试图理解以下代码中的原因:插入新节点作为特定节点的子节点不起作用。 代码是:

public void InsertNodeToTreeLDR(TreeNode newNode)
        {
            var currRoot = Root;
            InsertNodeToTreeHelper(ref currRoot, newNode);           
        }

        private void InsertNodeToTreeHelper(ref TreeNode currTreeRoot, TreeNode newNode)
        {
            if (currTreeRoot == null)
            {
                currTreeRoot = newNode;
                return;
            }

            else if (newNode.Data.CompareTo(currTreeRoot.Data) >= 0)
            {
                var currRootLeftChild = currTreeRoot.Leftchild;
                InsertNodeToTreeHelper(ref currRootLeftChild, newNode);
            }

            else
            {
                var currRootRightChild = currTreeRoot.RightChild;
                InsertNodeToTreeHelper(ref currRootRightChild, newNode);
            }

        }

注意:
我不想在这里包含所有代码,所以这个函数是 Tree 类的一部分,它包含 TreeNode 类型的根。
认为您已经拥有带有数据 == 2 (int) 的根树,并且想要像数据 == 1 一样添加新的左子节点。
在我的实现中,节点与其子节点之间的链接不起作用。

4

2 回答 2

2

您似乎对通过引用传递的作用以及它如何与 C# 中的引用类型交互感到困惑。这段代码什么都不做:

public void InsertNodeToTreeLDR(TreeNode newNode)
{
    var currRoot = Root;
    InsertNodeToTreeHelper(ref currRoot, newNode);           
}

要了解为什么它什么都不做,让我们一次过一行。

var currRoot = Root;

这一行定义了一个名为的变量currRoot,然后告诉TreeNode它引用由Root. 所以现在currRootRoot指的是同一个 TreeNode实例。

InsertNodeToTreeHelper(ref currRoot, newNode);

这里我们通过引用传递变量。 currRoot这意味着InsertNodeToTreeHelper允许该方法修改 的值currRoot。但请记住,的值currRoot是对 a 的引用TreeNode因此如果currRoot修改了值,您只是告诉特定变量指向其他地方,它不会对值做任何事情Root(这也是对一些TreeNode例子)。

如果不清楚,让我尝试用一​​个更简单的例子来说明这一点:

public void ClearTree()
{
    var currRoot = Root;
    ClearTreeHelper(ref currRoot);           
}

private void ClearTreeHelper(ref TreeNode currTreeRoot)
{
    currTreeRoot = null;
}

这个代码示例实际上与编写此代码相同:

public void ClearTree()
{
    var currRoot = Root;
    // ClearTreeHelper       
    currRoot = null;  
}

希望这可以更清楚地说明为什么您的引用传递没有做任何事情。

现在,对于您的实际问题,据我所知,您真正想要的是这样的:

public void InsertNodeToTreeLDR(TreeNode newNode)
{
    if( Root == null )
    {
        Root = newNode;
        return;
    }

    InsertNodeToTreeHelper( Root, newNode );           
}

private void InsertNodeToTreeHelper(TreeNode root, TreeNode newNode)
{
    if (newNode.Data.CompareTo(root.Data) >= 0)
    {
        if( root.LeftChild == null )
        {
            root.LeftChild = newNode;
        }
        else
        {
            InsertNodeToTreeHelper( root.LeftChild, newNode);
        }
    }
    else
    {
        if( root.RightChild == null )
        {
            root.RightChild = newNode;
        }
        else
        {
            InsertNodeToTreeHelper( root.RightChild, newNode);
        }
    }
}

这也可以在没有递归的情况下完成(我建议这样做,我认为它会极大地简化代码并消除对辅助方法的需求)。

于 2014-05-20T15:53:48.263 回答
0

一个问题是您通过引用传递了一个局部变量:

var currRootLeftChild = currTreeRoot.Leftchild;
InsertNodeToTreeHelper(ref currRootLeftChild, newNode);

...在上面的代码中, currRootLeftChild 是一个局部变量。如果它被函数 InsertNodeToTreeHelper 完全修改,那么当 currRootLeftChild 超出范围时,这些更改将被丢弃。您需要传递 currTreeRoot 的引用,而不是本地引用,才能使此代码正常工作。

于 2014-05-20T15:02:00.673 回答