有这种数据结构可以交换数组访问的性能,而不需要在清除数组时对其进行迭代。您需要为每个条目保留一个世代计数器,以及一个全局世代计数器。“清除”操作会增加生成计数器。在每次访问时,您都要比较本地生成计数器和全局生成计数器。如果它们不同,则将该值视为“干净”。
这是最近在Stack Overflow上的答案中提到的,但是我不记得这个技巧是否有正式名称。可以?
如果只需要放松节点的一小部分子集,并且必须重复进行一次,Dijkstra算法就是一个用例。
有这种数据结构可以交换数组访问的性能,而不需要在清除数组时对其进行迭代。您需要为每个条目保留一个世代计数器,以及一个全局世代计数器。“清除”操作会增加生成计数器。在每次访问时,您都要比较本地生成计数器和全局生成计数器。如果它们不同,则将该值视为“干净”。
这是最近在Stack Overflow上的答案中提到的,但是我不记得这个技巧是否有正式名称。可以?
如果只需要放松节点的一小部分子集,并且必须重复进行一次,Dijkstra算法就是一个用例。
Answers:
前述方法要求每个单元能够容纳足够大的数目以容纳可能需要重新初始化阵列的次数,这是相当大的空间损失。如果一个时隙是能够保持其中将永远不会被合法地写入的至少一个值,可避免任何其他(非恒定)的空间在加入为代价惩罚O(Wlg(N))
时间损失,其中W
是的数目不同之间写入阵列的槽清除操作,N
是数组的大小。例如,假设一个将存储从-2,147,483,647到2,147,483,647(但从不包括-2,147,483,648)的整数,并且一个人希望将空白数组项读取为零。首先用-2,147,483,648填充数组(调用该值B
)。读取应用程序的阵列插槽时,报告值B
为零。书写阵列时隙之前I
,检查它是否保持B
并且如果是这样并且I
是大于一,一个零存储槽I/4
用于该位置进行类似的检查之后(并且,如果它保持B
,I/16
等等)。
要清除数组,请从I
0或1开始,具体取决于数组的基数(所描述的算法适用于任何一种)。然后重复以下过程:如果item I
为B
,则递增,I
并且如果这样得出四的倍数,则将其除以4(如果除以得出的值为1,则终止)。如果item I
不是B
,则存储B
在那里并乘以I
四(如果I
从零开始,乘以四将使其保持零,但是由于item 0将为空白,因此I
将递增)。
注意,可以用其他数字代替上面的常数“ 4”,较大的值通常需要较少的工作标签,而较小的值通常需要较少的工作清除;由于必须清除带有标签的阵列插槽,因此几乎可以肯定,最佳值为3或4。由于值四肯定接近最佳值,比二或八好,并且比其他任何数更方便,所以这似乎是最合理的选择。
我将其称为“惰性数组单元重新初始化”,但它似乎没有任何已建立的名称(即,该名称被广泛使用)。
该算法很聪明,但是非常专业并且适用于非常狭窄的区域。