标准排序函数文献将告诉您,排序一般可以(合并,快速)在N log N
中完成。
例如,如果我有这个列表:[1,6,3,3,4,2]
它将在NlogN时间内对此进行排序:[1,2,3,3,4,6]
如果我有一个列表,我按第一个属性排序,然后第二个属性怎么办?
像这样:[(1,1),(6,3),(3,4),(3,1),(2,8)]
对此:[(1,1),(2,8),(3,1),(3,4),(6,3)]
时间复杂度是多少?
我想到的是,如果所有的第一个索引都是相同的,那么你只是再次进行N log N
,所以同样如此。如果有一堆不同的第一个索引,你会重新排序一堆小集。
答案 0 :(得分:1)
合并排序(或快速排序)执行O(N log N)
比较。它的时间复杂度为O(N log N * time_to_compare_two_elements)
。比较一对元素的时间复杂度是常数(如果比较两个元素的时间是常数)。因此,排序对数组的时间复杂度也是O(N log N)
。
答案 1 :(得分:1)
首先,您将比较每对的第一个元素并进行排序。使用NlogN。如果第一个元素相同,现在将比较秒元素。需要NlogN。总共2Nlogn,这只是NlogN
希望这有助于!!
答案 2 :(得分:1)
如果您不了解有关数据的更多信息,则无法保证比O(N log(N))
更好:所有第一个元素可能相同,然后您将被排除第二个元素正常。
O(N log(N))
约束意味着什么:如果您必须对数据进行通用比较排序,则无法对此进行改进。完全停止。
如果你做有进一步的信息,那么(正如你直观推理的那样)你可能会对此有所改进。例如,假设对于作为对中第一个元素至少出现一次的任何x
,大约有log(N)
个对作为其第一个元素x
。在这种情况下,您的第一次传递可以更有效:
d = {}
for x, y in L:
xL = d.setdefault(x, [])
xL.append(y)
xs_sorted = sorted(d.keys())
这是(大致)O(N)
,因为d.keys()
有N / log(N)
元素。接下来,您可以对每个N / log(N)
个子列表进行排序,每个子列表的大小为log(N)
:
L_sorted = []
for x in xs_sorted:
ys_sorted = sorted(d[x])
for y in ys_sorted:
L_sorted.append((x, y))
这是O(N log(log(N)))
,它在运行时占主导地位 - 但优于O(N log(N))
!
答案 3 :(得分:0)
Nlog(N)复杂度存在一个常数因素,这取决于计算机在决定订单之前如何进行比较。例如,如果对字符进行排序,则Nlog(N)的复杂性将变为
Nlog(N)*最大字符串大小的长度