Python內置方法的時間複雜度(轉)

Python內置方法的時間複雜度(轉)

原文:http://www.orangecube.net/python-time-complexity

本文翻譯自Python Wiki
本文基於GPL v2協議,轉載請保留此協議。

本頁面涵蓋了Python中若干方法的時間複雜度(或者叫“大歐”,“Big O”)。該時間複雜度的計算基於當前(譯註:至少是2011年之前)的CPython實現。其他Python的實現(包括老版本或者尚在開發的CPython實現)可能會在性能表現上有些許小小的差異,但一般不超過一個O(log n)項。

本文中,’n’代表容器中元素的數量,’k’代表參數的值,或者參數的數量。

列表(list

以完全隨機的列表考慮平均情況。

列表是以數組(Array)實現的。最大的開銷發生在超過當前分配大小的增長,這種情況下所有元素都需要移動;或者是在起始位置附近插入或者刪除元素,這種情況下所有在該位置後面的元素都需要移動。如果你需要在一個隊列的兩端進行增刪的操作,應當使用collections.deque(雙向隊列)

操作平均情況最壞情況
複製O(n)O(n)
append[注1]O(1)O(1)
插入O(n)O(n)
取元素O(1)O(1)
更改元素O(1)O(1)
刪除元素O(n)O(n)
遍歷O(n)O(n)
取切片O(k)O(k)
刪除切片O(n)O(n)
更改切片O(k+n)O(k+n)
extend[注1]O(k)O(k)
排序O(n log n)O(n log n)
列表乘法O(nk)O(nk)
x in sO(n) 
min(s), max(s)O(n) 
計算長度O(1)O(1)

雙向隊列(collections.deque

deque (double-ended queue,雙向隊列)是以雙向鏈表的形式實現的 (Well, a list of arrays rather than objects, for greater efficiency)。雙向隊列的兩端都是可達的,但從查找隊列中間的元素較爲緩慢,增刪元素就更慢了。

操作平均情況最壞情況
複製O(n)O(n)
appendO(1)O(1)
appendleftO(1)O(1)
popO(1)O(1)
popleftO(1)O(1)
extendO(k)O(k)
extendleftO(k)O(k)
rotateO(k)O(k)
removeO(n)O(n)

集合(set)

未列出的操作可參考 dict —— 二者的實現非常相似。

操作平均情況最壞情況
x in sO(1)O(n)
並集 s|tO(len(s)+len(t)) 
交集 s&tO(min(len(s), len(t))O(len(s) * len(t))
差集 s-tO(len(s)) 
s.difference_update(t)O(len(t)) 
對稱差集 s^tO(len(s))O(len(s) * len(t))
s.symmetric_difference_update(t)O(len(t))O(len(t) * len(s))

由源碼得知,求差集(s-t,或s.difference(t))運算與更新爲差集(s.difference_uptate(t))運算的時間複雜度並不相同!前者是將在s中,但不在t中的元素添加到新的集合中,因此時間複雜度爲O(len(s));後者是將在t中的元素從s中移除,因此時間複雜度爲O(len(t))。因此,使用時請留心,根據兩個集合的大小以及是否需要新集合來選擇合適的方法。

集合的s-t運算中,並不要求t也一定是集合。只要t是可遍歷的對象即可。

字典(dict)

下列字典的平均情況基於以下假設:
1. 對象的散列函數足夠擼棒(robust),不會發生衝突。
2. 字典的鍵是從所有可能的鍵的集合中隨機選擇的。

小竅門:只使用字符串作爲字典的鍵。這麼做雖然不會影響算法的時間複雜度,但會對常數項產生顯著的影響,這決定了你的一段程序能多快跑完。

操作平均情況最壞情況
複製[注2]O(n)O(n)
取元素O(1)O(n)
更改元素[注1]O(1)O(n)
刪除元素O(1)O(n)
遍歷[注2]O(n)O(n)

注:
[1] = These operations rely on the “Amortized” part of “Amortized Worst Case”. Individual actions may take surprisingly long, depending on the history of the container.

[2] = For these operations, the worst case n is the maximum size the container ever achieved, rather than just the current size. For example, if N objects are added to a dictionary, then N-1 are deleted, the dictionary will still be sized for N objects (at least) until another insertion is made.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章