鉴于此排序算法,您如何表达其时间复杂度?
Originally presented here (partial archive)。
#!/bin/bash
function f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
f "$1" &
shift
done
wait
example usage:
./sleepsort.bash 5 3 6 3 6 3 1 4 7
答案 0 :(得分:28)
答案 1 :(得分:19)
似乎没有人解决的一点是sleep
是如何实现的。最终,它们最终会出现在某个调度程序中,操作复杂性将取决于所使用的调度算法。例如,如果将sleep
作为事件放在优先级队列中,您可能会得到等同于heapsort的东西,其复杂度为 O(n log n)。天真的调度算法可能会导致 O(n ^ 2)。
答案 2 :(得分:15)
我认为paxdiablo距离最近,但不是正确的原因。时间复杂性忽略了真实硬件上的问题,例如高速缓存大小,内存限制以及在这种情况下有限数量的进程和调度程序的操作。
基于Wikipedia page for Time complexity我会说答案是你无法确定运行时的复杂性,因为如果定义为:
通常通过计算算法执行的基本操作的数量来估计时间复杂度,其中基本操作花费固定的时间量来执行。因此,算法所花费的时间量和基本操作的数量最多相差恒定因子。
然后我们不能谈论这个算法的运行时复杂性,因为基本操作所花费的时间差别很大,所花费的时间差异会超过一个常数因子。
答案 3 :(得分:11)
该算法的时间复杂度和流程复杂度均为O(braindead)
。
如果数据集中有足够大的值,您将等待答案,直到太阳爆炸。
如果数据集大小足够大,你将
(2,9,9,9,9,9,...,9,9,1)
不会正确排序1
和2
。在这种情况下,时间复杂度无关紧要。你不能得到任何不如“错误”的优化。
可以使用复杂性分析来比较算法,因为数据集大小会发生变化,但是当算法首先变得荒谬时,不能这样做: - )
答案 4 :(得分:3)
虽然看起来像线性,但我认为复杂性仍然是O(log(n)* max(输入))。
当我们谈论渐近时间复杂度时,它意味着当n增长无限大时需要花费多少时间。
基于比较的排序算法不能比O(n * log(n))更快,而Sleep-Sort实际上是基于比较的:
进程睡眠n秒并唤醒。操作系统需要从所有睡眠过程中找到最少的剩余睡眠时间,并且如果它是关于时间的话,将其唤醒。
这将需要一个优先级队列,它需要O(logN)时间插入一个元素,O(1)找到最小元素,O(logN)删除最小元素。
当n变得非常大时,唤醒进程需要1秒以上的时间,这会使其大于O(n)。
答案 5 :(得分:2)
如果您阅读该主题,您会看到您的问题已经得到解答。时间复杂度为O(max(input))
,操作复杂度(操作次数)为O(n)
。
答案 6 :(得分:2)
我和Jordan在一起,除了我认为挂钟时间复杂度更好地表示为O(2 ^ m),其中m是每个项目的大小,而不是O(max(输入))。 / p>
如果每个项目的大小为m,则最大项目的整数值为2 ^ m(减去1,但没有人关心这一点)。通过构造,算法要求设置时间小于1,即常数。
因此挂钟时间复杂度为O(2 ^ m),操作计数复杂度为O(n)。
考虑到建立时间的修改算法可能具有挂钟时间复杂度O(2 ^ m + n)。例如,它可以记录开头的当前时间,计算base_time = start_time + k*len(list)
(对于某些适当的常数k),然后使线程休眠直到时间base_time+i
。那么k*len(list)
显然是O(n),而i
与前面一样是O(2 ^ m),总共为O(2 ^ m + n)。