我所说的结构是:
x.push()
操作复杂度O(log n)- O(log n)查找元素的复杂度
- O(n)复杂度进行计算
list(x)
将被排序
我也有一个有关性能的相关问题list(...).insert(...)
,现在在这里。
我所说的结构是:
x.push()
操作复杂度O(log n)list(x)
将被排序我也有一个有关性能的相关问题list(...).insert(...)
,现在在这里。
Answers:
标准Python列表不以任何形式排序。标准的heapq模块可用于将O(log n)追加到现有列表中,并删除O(log n)中最小的模块,但在定义中不是排序列表。
您的big-O需求是否有特定原因?还是您只是想要它快?所述sortedcontainers模块是纯Python和快速(如在快速作为-C实现比如blist和rbtree)。
在性能比较表明它与基准测试blist的排序列表类型更快或看齐。还要注意,rbtree,RBTree和PyAVL提供排序的dict和set类型,但没有排序的列表类型。
如果需要性能,请始终记住要进行基准测试。在它还显示基准比较之前,应该怀疑使用Big-O表示法证明快速的模块。
免责声明:我是Python sortedcontainers模块的作者。
安装:
pip install sortedcontainers
用法:
>>> from sortedcontainers import SortedList
>>> l = SortedList()
>>> l.update([0, 4, 1, 3, 2])
>>> l.index(3)
3
>>> l.add(5)
>>> l[-1]
5
0.0845024989976
进行了比较:SortedList.add()与0.596589182518
bisect.insort(),因此速度相差7倍!而且我希望速度差距会随着列表的长度而增加,因为sortedcontainers插入排序在O(log n)中起作用,而bisect.insort()在O(n)中起作用。
O(n)
尽管我仍然从未检查过基本Python列表操作的“大O”速度,但bisect
在这种情况下,标准模块可能也值得一提:
import bisect
L = [0, 100]
bisect.insort(L, 50)
bisect.insort(L, 20)
bisect.insort(L, 21)
print L
## [0, 20, 21, 50, 100]
i = bisect.bisect(L, 20)
print L[i-1], L[i]
## 20, 21
PS。啊,对不起,bisect
在提到的问题中被提及。不过,我认为,如果此信息在这里,不会有太大危害)
PPS。而CPython的名单实际上是数组(不是,比方说,skiplists或等)。好吧,我想它们一定很简单,但就我而言,这个名称有点误导。
因此,如果我没记错的话,平分/列表速度可能是:
更新。在评论中进行讨论之后,让我在这里链接这些SO问题:如何实现Python的列表以及什么是Python列表函数的运行时复杂性
在Python上实现您自己的排序列表可能并不困难。以下是概念证明:
import bisect
class sortlist:
def __init__(self, list):
self.list = list
self.sort()
def sort(self):
l = []
for i in range(len(self.list)):
bisect.insort(l, self.list[i])
self.list = l
self.len = i
def insert(self, value):
bisect.insort(self.list, value)
self.len += 1
def show(self):
print self.list
def search(self,value):
left = bisect.bisect_left(self.list, value)
if abs(self.list[min([left,self.len-1])] - value) >= abs(self.list[left-1] - value):
return self.list[left-1]
else:
return self.list[left]
list = [101, 3, 10, 14, 23, 86, 44, 45, 45, 50, 66, 95, 17, 77, 79, 84, 85, 91, 73]
slist = sortlist(list)
slist.show()
slist.insert(99)
slist.show()
print slist.search(100000000)
print slist.search(0)
print slist.search(56.7)
=========结果============
[3、10、14、17、23、44、45、45、50、66、73、77、79、84、85、86、91、95、101]
[3、10、14、17、23、44、45、45、50、66、73、77、79、84、85、86、91、95、99、101]
101
3
50
memcpy
仍然是O(n)运算。我不确定Python如何精确实现列表,但是我敢打赌,它们存储在连续内存中(肯定不是链接列表)。如果确实如此,则bisect
您演示使用的插入将具有复杂度O(n)。