#stack-overflow #tree #drop #leaf-node #tree-traversal #no-std

no-std deep_safe_drop

安全释放深层次树,否则可能会导致栈溢出

2个不稳定版本

0.1.0 2024年6月18日
0.0.3 2020年5月2日

#437Rust模式

Unlicense

16KB
122

deep_safe_drop

安全释放深层次树,否则可能会导致栈溢出。

不需要任何分配,并重新使用树中现有的空间来实现回溯树分支,而不是调用栈。

没有unsafe代码。

no_std,因此可以在受限环境中使用(例如,没有堆分配)。

提供

  • deep_safe_drop 函数,可以从您的 Drop::drop 实现中调用。

  • DeepSafeDrop 特征,由使用 deep_safe_drop 的您的节点类型实现。

  • Link 特征,由涉及 DeepSafeDrop 的您的链接类型实现。

通过将树转换为叶节点来避免栈溢出,即不再有任何子节点,递归地对子节点执行相同的转换,但以迭代方式执行,在遇到叶节点时释放叶节点,将子节点转换为叶节点,在隐式编译器添加的递归调用自动释放字段之前,这样在递归调用执行时,所有节点,包括根节点,都已变为叶节点,从而避免了对该最终释放的递归调用。

我们不是使用递归函数调用(即记录有限调用栈上的连续调用)来使工作回溯到树分支以遍历其他分支(如编译器添加的最终释放所做的,这可能会造成栈溢出),而是重新使用每个节点的链接来记录必须回溯到哪个父节点。因此,无论需要多深,我们都保证已经有足够的空间用于我们的“连续调用”,并且可以重新使用这个空间,因为这些链接之前包含的内容已经会被释放。

变异步骤的简单示例(节点在作为叶节点移除时被释放)

Initial:   Step 1:    Step 2:    Step 3:
  a          a          a          a    
   ⭨          ⭦          ⭦              
    b           b          b             
   ⭩ ⭨        ⭧ ⭨          ⭨            
  c   d       c   d          d           
 ⭩ ⭨          ⭨                         
e   f          f                        

注意:最初,a 链接到 b,而 b 链接到 c,但在第一步之后,c 链接到 b,而 b 链接到 a。这是通过重用节点的链接空间来保存父节点,以便稍后遍历回该节点,从而实现向步骤 2 和 3 的转换。所有步骤都是通过同一单个函数调用中的循环来转换的,通过移动游标在树中上下移动。

请参阅测试以获取不同类型和不同形状的示例。

无运行时依赖