Visual c++ 迭代八叉树遍历

Visual c++ 迭代八叉树遍历,visual-c++,octree,Visual C++,Octree,虽然我已经尝试过用二叉树遍历的方法来实现迭代八叉树遍历,但我仍然无法理解迭代八叉树遍历的过程。对于我的问题,我有八叉树节点,它们有子指针和父指针,我想迭代,只在堆栈中存储叶节点。 另外,迭代遍历是否比递归遍历更快?取决于您的目标是什么。是否尝试查找节点是否可见、光线是否与其边界框相交,或者节点中是否包含点 让我们假设您正在执行最后一个操作,检查节点中是否包含/应该包含一个点。我将向Octnode添加一个方法,该方法获取一个点并检查它是否位于Octnode的边界框内。如果它返回true,否则返回f

虽然我已经尝试过用二叉树遍历的方法来实现迭代八叉树遍历,但我仍然无法理解迭代八叉树遍历的过程。对于我的问题,我有八叉树节点,它们有子指针和父指针,我想迭代,只在堆栈中存储叶节点。
另外,迭代遍历是否比递归遍历更快?

取决于您的目标是什么。是否尝试查找节点是否可见、光线是否与其边界框相交,或者节点中是否包含点

让我们假设您正在执行最后一个操作,检查节点中是否包含/应该包含一个点。我将向Octnode添加一个方法,该方法获取一个点并检查它是否位于Octnode的边界框内。如果它返回true,否则返回false,非常简单。从这里,调用一个从头部节点开始的向下钻取方法,检查每个子节点,简单的“for”循环,看看它位于哪个八进制节点,它最多只能是一个

这里是迭代与递归算法发挥作用的地方。如果需要迭代,只需存储指向当前节点的指针,并将该指针从head节点交换到包含点的节点。然后继续往下钻,直到达到最大深度,或者找不到包含它的八进制节点。如果需要递归解决方案,则将在找到点的Octnode上调用此向下搜索方法


我不会说迭代和递归在速度方面有很大的性能差异,但在内存性能方面可能有差异。每次递归时,都会在堆栈上添加另一个调用深度。如果您有一个大的八叉树,这可能会导致大量调用,可能会破坏堆栈

取决于你的目标是什么。是否尝试查找节点是否可见、光线是否与其边界框相交,或者节点中是否包含点

让我们假设您正在执行最后一个操作,检查节点中是否包含/应该包含一个点。我将向Octnode添加一个方法,该方法获取一个点并检查它是否位于Octnode的边界框内。如果它返回true,否则返回false,非常简单。从这里,调用一个从头部节点开始的向下钻取方法,检查每个子节点,简单的“for”循环,看看它位于哪个八进制节点,它最多只能是一个

这里是迭代与递归算法发挥作用的地方。如果需要迭代,只需存储指向当前节点的指针,并将该指针从head节点交换到包含点的节点。然后继续往下钻,直到达到最大深度,或者找不到包含它的八进制节点。如果需要递归解决方案,则将在找到点的Octnode上调用此向下搜索方法


我不会说迭代和递归在速度方面有很大的性能差异,但在内存性能方面可能有差异。每次递归时,都会在堆栈上添加另一个调用深度。如果您有一个大的八叉树,这可能会导致大量调用,可能会破坏堆栈

这确实类似于二叉树遍历,但需要存储一些中间信息。递归算法本身不会慢一些,但会为O(log8)递归调用使用更多的堆栈空间(八叉树中10亿个元素大约有10个级别)。 迭代算法也需要同样数量的空间来提高效率,但如果担心堆栈溢出,可以将其放入堆中

递归地执行(伪代码):

实现迭代算法的最简单方法是使用堆栈或队列进行深度优先或呼吸优先遍历:

 function traverse_iter_dfs(octree):
     stack = empty
     push_stack(root_node)
     while not empty (stack):
         node = pop(stack)
         collect value(node)
         for child in children(node):
             push_stack(child)
将堆栈替换为队列,您将获得呼吸优先搜索。然而,我们正在O(7*(log8n))节点区域中存储一些东西,我们还需要遍历这些节点。如果你想一想,这是较小的邪恶,但除非你需要穿越真正的大树。唯一的另一种方法是使用父指针,当您在子对象中完成时,然后您需要以某种方式选择下一个同级对象

但是,如果不预先存储当前节点(相对于其同级)的索引,则只能搜索父节点的所有节点以查找下一个同级节点,这实际上会使要完成的工作量增加一倍(对于每个节点,不仅要循环子节点,还要循环同级节点)。另外,看起来您至少需要记住您已经访问了哪些节点,因为通常无法确定是继续向下还是返回树上(证明我错了)


总而言之,我建议不要搜索这样的解决方案。

这确实类似于二叉树遍历,但您需要存储一些中间信息。递归算法本身不会慢一些,但会为O(log8)递归调用使用更多的堆栈空间(八叉树中10亿个元素大约有10个级别)。 迭代算法也需要同样数量的空间来提高效率,但如果担心堆栈溢出,可以将其放入堆中

递归地执行(伪代码):

实现迭代算法的最简单方法是使用堆栈或队列进行深度优先或呼吸优先遍历:

 function traverse_iter_dfs(octree):
     stack = empty
     push_stack(root_node)
     while not empty (stack):
         node = pop(stack)
         collect value(node)
         for child in children(node):
             push_stack(child)
将堆栈替换为队列,您将获得呼吸优先搜索。然而,我们正在O(7*(log8n))节点区域中存储一些东西,我们还需要遍历这些节点。如果你想一想,这是较小的邪恶,但除非你需要穿越真正的大树。唯一的另一种方法是使用父指针,当您在子对象中完成时,然后您需要以某种方式选择下一个同级对象

但是,如果不预先存储当前节点的索引(相对于其同级),则只能搜索父节点的所有节点以查找