我想在这个成本模型下对数组A进行排序:
对于任何值x,形式A [i] = x的赋值的成本为1.此外,A [i] = A [j]的成本为1.
< / LI>其他操作,例如比较和分配for x = A [i](其中x不是数组中的位置)的成本为0.
问题:
给出排序数组A所需的最坏情况时间的下限。你的答案应该是n的精确表达,而不是使用渐近符号。
描述使用O(n)空间的排序算法。运行时应该与1中给出的下限完全匹配(确切地说,不是渐近)。
描述一种最适合此成本模型的就地排序算法。运行时应该与1中给出的绑定完全匹配(确切地说,不是渐近)。
我的尝试:
ñ。这是因为,在最坏的情况下,数组中的n个元素位于它们不应该位于的索引中。因此,需要n个赋值才能按排序顺序获取数组。
我在psudo代码中的算法:
def weird_sort(A):
B = an array the same size of A
C = an array of bools (default True) the same size of A
for i in range(0, A.size):
min = first index in c that is True
for j in range(0, A.size):
if (A[j] < A[min]) and (C[j]):
min = j
B[i] = A[min]
C[i] = False
A = B
我相信这需要花费n个时间才能运行,因为我们唯一一次将任何内容分配给A是在最后一行,我们将B的内容复制到A中。
答案 0 :(得分:0)
我认为就地允许O(1)
个额外变量,否则我认为不可能
首先让我们解决子问题:给定i
,找到应该在i
位置的数字。因为比较是免费的,所以可以使用暴力。
现在复制第一个元素(到另一个变量),找到最小元素并将其放在位置1.现在这个元素位于i
位置。让我们找到位于i
位置的元素并将其复制到此处(假设它位于位置j
),现在找到属于位置j
的元素,等等。最终我们找到了我们最初复制的元素,然后把它放回去因此,我们使用k
赋值(在循环结构中)将k
个变量设置到它们的位置。
现在对所有其他元素执行相同操作。您无法记住每个变量是否放在原位,但您可以免费检查它是否在其位置。
如果A中存在相同的元素,则应该更仔细地进行,但它仍然可以正常工作
答案 1 :(得分:0)
虽然在讨论高效排序算法时,我们通常倾向于谈论快速排序,这种算法优化了比较次数。
但是,其他算法会尝试优化内存访问次数(如您的情况)。其中一些被称为缓存遗忘算法(不对特定的内存层次结构参数做出假设)和缓存感知(它们针对特定的内存层次结构进行了调整)。您可以找到多种此类算法,因此您可能有兴趣了解它们。
作为示例,Harald Prokop's PhD thesis讨论了缓存无关的算法,并提出了分布排序,它对可能适合内存层次结构的较低分区的子组中的数据进行部分排序。
分发排序使用
O(n ln(n))
工作并导致O(1+ (L/n)*(1+logz(n))
缓存未命中以对 n 元素进行排序。
其中 L 是缓存库的大小, z 是缓存本身的大小。性能模型仅假设只有一个缓存级别,尽管它由于不经意的属性而适应所有缓存级别。
基本概念是赋值成本会根据元素在内存层次结构中的位置而改变。