这是功能:
c = []
def badsort(l):
v = 0
m = len(l)
while v<m:
c.append(min(l))
l.remove(min(l))
v+=1
return c
虽然我意识到这是一种非常低效的排序方式,但我想知道这样一个函数的时间复杂度是多少,因为虽然它没有嵌套循环,但它会多次重复循环。
答案 0 :(得分:4)
以下是一些有用的信息,可帮助您了解如何找到函数的复杂性。
对于第一点,您会看到终止条件为v < m
,其中v
最初为0,m
是列表的大小。由于v
在每次迭代时递增1,因此循环最多运行(至少)N
次,其中N
是列表的大小。
现在,第二点。每次迭代我们都有 -
c.append(min(l))
其中min
是线性操作,花费O(N)
时间。 append
是一个持续的操作。
接下来,
l.remove(min(l))
同样,min
是线性的,remove
也是如此。因此,您有O(N)
+ O(N)
,即O(N)
。
总之,您需要O(N)
次迭代,每次迭代O(N)
,使其成为O(N ** 2)
或二次。
答案 1 :(得分:4)
假设n = len(l)
。
外环运行n次。内循环中的min()
比l(这里的优化空间)运行两次,但是对于递增递减的数字(对于循环的每次迭代,l的长度减少,因为每次从列表中删除一个项目)。
这种复杂性为2 * (n + (n-1) + (n-2) + ... + (n-n))
。
这等于2 * (n^2 - (1 + 2 + 3 + ... + n))
。
括号中的第二项是triangular number,并且分为n*(n+1)/2
。
因此,您的复杂性等于2*(n^2 - n*(n+1)/2))
。
这可以扩展到2*(n^2 - n^2/2 - n/2)
,
并简化为n^2 - n
。
BigO表示法对整体增长趋势感兴趣,而不是函数的精确增长率。 p>
在BigO表示法中,常量被删除。由于没有常数,因此我们仍然使用n^2 - n
。
此外,在BigO表示法中,只考虑主导术语。 <{1}}占据n^2
的主导地位,因此n
被删除。
这意味着BigO中的答案是n
,即二次复杂度。
答案 2 :(得分:3)
此问题的时间复杂度为O(n^2)
。虽然代码本身只有一个明显的循环,while
循环,min
和max
函数都是O(n)
实现,因为在最坏的情况下,它必须扫描整个列表以查找相应的最小值或最大值。 list.remove
是O(n)
因为它必须遍历列表,直到它找到第一个目标值,在最坏的情况下,它可能在最后。由于方法的巧妙实施,list.append
已摊销 O(1)
,因为list.append
技术上O(n)/n = O(1)
推送n
个对象:
def badsort(l):
v = 0
m = len(l)
while v<m: #O(n)
c.append(min(l)) #O(n) + O(1)
l.remove(min(l)) #O(n) + O(n)
v+=1
return c
因此,有:
Outer(O(n)) * Inner(O(n)+O(n)+O(n)) = Outer(O(n)) * Inner(O(n))
O(n)+O(n)+O(n)
可以合并为O(n)
,因为大o会衡量最坏情况。因此,通过组合外部和内部的复杂性,最终的复杂性是O(n^2)
。