Python 绘制(Cormen)红黑树插入时出现奇怪结果
我根据Cormen的《算法简介》中的伪代码,在Python中用红黑树实现 我想亲眼看到我的Python 绘制(Cormen)红黑树插入时出现奇怪结果,python,big-o,red-black-tree,Python,Big O,Red Black Tree,我根据Cormen的《算法简介》中的伪代码,在Python中用红黑树实现 我想亲眼看到我的insert实际上是O(logn),因此我绘制了在树中插入n=1,10,20,…,5000个节点所需的时间 结果是: x-轴是n,y-轴是以毫秒为单位的时间 在我看来,这张图更像是线性的,而不是对数的。有什么可以解释呢?5000可能不够大,无法真正“看到”对数——请尝试在50000和500000处运行。如果需要2秒20秒,那么线性增长是有意义的。如果需要更少的时间,那么对数是有意义的。如果你把大多数“简单
insert
实际上是O(logn)
,因此我绘制了在树中插入n=1,10,20,…,5000个节点所需的时间
结果是:
x
-轴是n
,y
-轴是以毫秒为单位的时间
在我看来,这张图更像是线性的,而不是对数的。有什么可以解释呢?5000
可能不够大,无法真正“看到”对数——请尝试在50000
和500000
处运行。如果需要2秒20秒,那么线性增长是有意义的。如果需要更少的时间,那么对数是有意义的。如果你把大多数“简单”函数放大得足够近,结果看起来是线性的。对于任何“为什么”的问题总是有一些猜测。我怀疑您看到的跳跃与系统内存管理有关。如果系统必须分配更大的内存空间以继续增长,则会增加一定的时间来完成整个程序的处理。如果您向节点添加了一个“payload”字段,从而增加了所需的存储空间量(我是正确的),那么跳转将更频繁地发生
顺便说一句,这是一个很好的图表。好的,因此图表显示了在树中插入n
元素的成本度量,其中x轴是我们插入的元素数量,y轴是总时间
让我们调用一个函数,该函数汇总将n个元素插入到树中所需的时间f(n)
然后我们可以大致了解f
的外观:
f(1) < k*log(1) for some constant k.
f(2) < k*log(1) + k*log(2) for some constant k
...
f(n) < k * [log(1) + log(2) + ... + log(n)] for some constant k.
我们可以看看维基百科,看看log(n!)
是什么样子的。看看这篇文章中的图表。你看起来应该很熟悉。:)
也就是说,我认为你这样做是偶然的:
for n in (5000, 50000, 500000):
startTime = ...
## .. make a fresh tree
## insert n elements into the tree
stopTime = ...
## record the tuple (n, stopTime - startTime) for plotting
并绘制了构建大小为n的树的总时间,而不是将一个元素插入大小为n的树的单个成本:
for n in range(50000):
startTime = ...
## insert an element into the tree
stopTime = ...
## record the tuple (n, stopTime - startTime) for plotting
Chris Taylor在评论中指出,如果绘制f(n)/n
,您将看到一个对数图。这是因为相当接近于log(n!)
的是n*log(n)
(参见维基百科页面)。所以我们可以回到我们的领域:
f(n) < k * log(n!) for some constant k
一些常数k的f(n)
并获得:
f(n) < k * n * log(n) for some constant k
f(n)
现在应该更容易看到,如果你用
f(n)
除以n
,你的图形将以对数的形状为界。对不起,你一定看到了使用pypy的预编辑版本。我相信这就是跳转的原因。所以50000
需要2.5秒,500000
需要30秒,根据你的猜测,这看起来是线性的,这正是我要发布的答案!扎克,如果你绘制f(n)/n
,你会看到你的日志图像白天一样清晰。
f(n) < k * n * log(n) for some constant k