因此,我尝试搜索填充了节点中Country
对象的二叉树T Data
。 Country
对象的String变量包含国家/地区的名称(countryName
),我想在文本框中搜索countryName
并返回一个布尔值。因此,它将遍历Country
个对象的二叉树,并将文本框字段中的值与countryName
匹配。可以将对象的值分别存储在节点中,但我更倾向于使用泛型类型。以下是我的搜索方法。
public Boolean Contains(T item)
{
return contains(item, ref root);
}
private Boolean contains(T item, ref Node<T> tree)
{
if (tree != null)
{
if (item.CompareTo(tree.Data)==0)
{
Console.WriteLine("Found");
return true;
}
return contains(item, ref tree.Left) || contains(item, ref tree.Right);
}
else
{
return false;
}
}
节点结构
public T Data;
public Node<T> Left;
public Node<T> Right;
public int balanceFactor;
public Node(T Data)
{
this.Data = Data;
Left = null;
Right = null;
}
答案 0 :(得分:0)
从不调用自身内部的函数,这最终会导致StackOverflowException。你应该做这样的事情;
Stack<T>
static bool Contains<T>(T item, Node<T> tree) {
Stack<Node<T>> stack = new Stack<Node<T>>();
stack.Push(tree); //Push the root node into the stack
Node<T> current;
do {
current = stack.Pop(); //Get the last item that was added to the stack and remove it at the same time
if (item.Equals(current.Data)) //If the item we just popped has its 'Data' property equal to the 'item'
{
Console.WriteLine("Found");
return true; //then return true
}
//Otherwise add the left and right nodes to the stack if they exist.
if(current.Left != null) stack.Push(current.Left);
if(current.Right != null) stack.Push(current.Right);
} while(stack.Count > 0); //If the stack still contains items, go back to the 'do'
//If we've reached this point we've searched the entire tree and found nothing
return false;
}
当你在程序中执行一个函数时,程序需要一些存储位置的方法,这称为堆栈。堆栈通常具有有限的大小,如果达到此限制并且您尝试进一步深度,则会抛出StackOverflowException。
基本上这就是你的功能在操作中的表现:
contains(contains(contains(contains(contains(contains(contains(contains(...
它必须考虑的深度级别通常不会出现在应用程序中,除非你做错了一些事情,比如在你自己内部调用一个函数,这就是你正在做的事情。
因此,不要让堆栈达到疯狂的深度,让我们只列出我们需要与我们搜索的内容进行比较的所有内容,并一路上将他们的孩子添加到同一个列表中。 / p>
这就是Stack<T>
类型的用武之地。尽管堆栈类型与程序堆栈共享,但堆栈类型并不相同。 Stack类型只是一个项目列表,它可以添加(Push(T)
),同时检索添加到列表中的最后一项,同时从列表中删除它({{1 }})。
因此,每次我们想要搜索节点时,我们不会将深度降低,而是在循环时将其添加到堆栈中。
答案 1 :(得分:0)
在二进制搜索树(BST)中,您必须以插入/搜索/删除项目时以相同排序顺序(使用相同比较器)的方式比较项目。您不能在插入中使用一个比较器(例如,比较国家/地区人口),而是在O(lg(N))
中的同一个BST中按名称搜索。
为了构建允许您按名称搜索国家/地区的BST,请使用像Func<of T, of T, of int>
这样的过程参数,或者在树构造函数中的.NET Framework IComparer<of T>
中非常常见。请参见SortedSet<of T>
类设计和SortedSet<of T>(IComparer<of T>)
构造函数。
示例实施:
Node<T> _root;
readonly IComparer<T> _comparer;
public bool Contains(T target)
{
return Contains(_root, target);
}
bool Contains(Node<T> root, T target)
{
if (root == null)
return false;
int cmp = _comparer.Compare(target, root.Data);
if (cmp == 0)
return true;
return cmp < 0 ? Contains(root.Left, target) : Contains(root.Right, target);
}
另请注意,在BST搜索实现中,仅在单个子树(左侧或右侧)上进行递归调用是非常重要的。
有关详细信息,请查看维基百科上的Binary search tree页面,SortedSet - custom order when storing a class object和有关StackOverflow的Using lambda expression in place of IComparer argument讨论。