我正在研究我一直在研究的深度搜索算法的替代方案。我的代码在这里发布有点太长了,但我写了一个简化版本来捕获重要的方面。首先,我创建了一个对象,我将其称为“BranchNode”,它包含一些值以及一组其他“BranchNode”对象。
class BranchNode : IComparable<BranchNode>
{
public BranchNode(int depth, int parentValue, Random rnd)
{
_nodeDelta = rnd.Next(-100, 100);
_depth = depth + 1;
leafValue = parentValue + _nodeDelta;
if (depth < 10)
{
int children = rnd.Next(1, 10);
branchNodes = new BranchNode[children];
for (int i = 0; i < children; i++)
{
branchNodes[i] = new BranchNode(_depth, leafValue, rnd);
}
}
}
public int CompareTo(BranchNode other)
{
return other.leafValue.CompareTo(this.leafValue);
}
private int _nodeDelta;
public BranchNode[] branchNodes;
private int _depth;
public int leafValue;
}
在我的实际程序中,我从其他地方获取数据......但是对于这个例子,我只是将一个Random对象的实例传递给我用来为每个BranchNode生成值的行。 ..我也手动创建10的深度,而我的实际数据将有任意代数。
作为对目标的快速解释,_nodeDelta包含分配给每个BranchNode的值。每个实例还维护一个leafValue,它等于当前BranchNode的_nodeDelta与其所有祖先的_nodeDeltas相加。我试图找到没有子节点的BranchNode的最大leafValue。
目前,我递归地遍历heirarchy搜索其子BranchNodes数组为null的BranchNodes(a.k.a:'无子'BranchNode),然后将它的leafValue与当前最高leafValue的leafValue进行比较。如果它更大,它将成为基准,并继续搜索,直到它查看所有BranchNodes。
我可以发布我的递归搜索算法,如果它有帮助,但它非常标准,并且工作正常。正如预期的那样,我的问题是,对于较大的heirarchies,我的算法需要很长时间来横向于内部结构。
我想知道我是否有任何其他可以选择的选项可能会产生更快的结果...具体来说,我一直试图绕着linq包围,但我甚至不确定它是否已构建做我正在寻找的,或者它是否更快。还有其他我应该研究的事情吗?
答案 0 :(得分:1)
也许您想要研究另一种数据索引结构:Here
它总是取决于您对数据所做的工作,但如果您在存储分层表单的每个元素上分配唯一ID,并创建存储的索引,那么优化将比微观更有意义。 - 优化你所做的部分。
此外,这也为搜索算法提供了一个非常不同的范例,它不使用递归,而是为ID和可能的索引增加内存的成本。
答案 1 :(得分:1)
如果您必须访问所有叶子节点,则无法加速搜索:无论如何,它都将通过所有节点。为加速树搜索而采用的典型技巧是以一种特殊的方式组织它们,简化了对树的搜索。例如,通过构建二叉搜索树,您可以进行搜索O(Log(N))
。您还可以在非叶节点中存储一些有用的值,稍后您可以从中构建搜索查询的答案。
例如,您可以决定将_bestLeaf“指向”存储到具有当前子树下所有叶子的最高_nodeDelta的叶子。如果您这样做,您的搜索将成为O(1)
查找。但是,您的插入和删除会变得更加昂贵,因为您需要在使用新Log-b(N)
返回root的路上更新最多_bestLeaf
项(b
是分支因素你的树。)
答案 2 :(得分:1)
我认为你应该考虑的第一件事就是离开N-Tree并转向二元搜索树。
这意味着所有节点只有2个孩子,更大的孩子和更小的孩子。
从那里开始,我会考虑平衡你的搜索树与红黑树或AVL之类的东西。这样,搜索树就是O(log n)。
以下是一些可以帮助您入门的链接:
http://en.wikipedia.org/wiki/Binary_search_tree http://en.wikipedia.org/wiki/AVL_tree http://en.wikipedia.org/wiki/Red-black_tree
现在,如果您已准备好让每个节点都能够拥有N个子节点,那么您应该注意以下几点:
N-log(n)
个孩子。答案 3 :(得分:0)
正如其他人所提到的,不同的数据结构可能就是您想要的。
如果需要保持数据结构相同,可以将递归展开为循环。虽然这种方法可能会快一点,但速度不会快几个数量级,但可能会占用更少的内存。