我正在尝试将节点添加到二叉搜索树中。 这里有一个比较两个节点的位置 - 您要添加的节点和树中的节点(第一次是根节点)。
...
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。
有什么建议吗? (抱歉可能不正确使用术语,我是新手)
答案 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
很容易理解这里发生了什么。
虽然我也让这个例子中的树变成了不可变的,但如果你在课堂上实现了setter,你可以更高效地完成这项工作,同时仍然不需要N160(8141(30) -- Roughing 1)
N33(8141(31) -- Roughing 2)
。