3
 public class TreeNode
{
    public TreeNode Left;
    public TreeNode Right;
    public int Data { get; set; }

    public TreeNode(int data)
    {
        Left = null;
        Right = null;
        Data = data;
    }
}



   public class BinarySearchTree
{
    private TreeNode _root;

    public BinarySearchTree()
    {
        _root = null;
    }

    public void Insert(int data)
    {
        TreeNode tempNode = null;

        Insert(_root, tempNode);
    } 

    private void Insert(TreeNode treeNode, TreeNode newNode)
    {
        newNode = new TreeNode(3);
        treeNode = new TreeNode(4);
   }

在这个例子中,public voidInsert(int data)方法基本上只是调用了私有方法,我在方法的末尾设置了一个断点public void Insert(int data)

并且通知_root仍然为空,并且tempNode是4。我不明白为什么?谁能解释一下?

4

3 回答 3

3

通过引用传递类使用ref关键字:

private void Insert(ref TreeNode treeNode, ref TreeNode newNode)
{
    newNode = new TreeNode(3);
    treeNode = new TreeNode(4);
}

在您的原始方法中,仅传递对类的引用的副本,而不是通过引用传递。因此,如果您这样做new,您只是替换类引用的本地副本,但调用方法仍保留原始引用值。因此,新创建的值不会返回给调用者。

改变你的Insert(data)方法(没有ref关键字编译器会给你一个错误):

public void Insert(int data)
{
    TreeNode tempNode = null;
    Insert(ref _root, ref tempNode);
} 

这实际上是编译器的要求,只是为了确保调用者知道在方法调用之后传递的对象可能被其他对象替换。

您可能还想了解out关键字。虽然ref参数应该在调用之前初始化,但参数应该out在方法内部进行初始化。

于 2012-12-06T17:45:30.697 回答
0

您正在传递引用类型,但它实际上传递了引用的副本。更新该副本不会更新原始版本。

要解决此问题,请让方法返回新值。或者,您可以重新编写函数以使用 out 参数。

private void Insert(out TreeNode treeNode, out TreeNode newNode)
{
    newNode = new TreeNode(3);
    treeNode = new TreeNode(4);
}
于 2012-12-06T17:45:43.987 回答
0

查看参数的out, 和ref修饰符。例如,您可以

private void Insert(ref TreeNode treeNode, TreeNode newNode)
于 2012-12-06T17:46:15.577 回答