2个不稳定版本
0.1.0 | 2024年6月18日 |
---|---|
0.0.3 | 2020年5月2日 |
#437 在 Rust模式
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 的转换。所有步骤都是通过同一单个函数调用中的循环来转换的,通过移动游标在树中上下移动。
请参阅测试以获取不同类型和不同形状的示例。