什么是好的特殊情况排序算法?


13

我有一个数据集,该数据集是多个以2D网格排列的对象。我知道我有严格的顺序,在每一行中从左到右增加,而在每一列中从上到下增加。例如,

  • 1 2 3
  • 4 6 7
  • 5 8 9

我可以改进天真的排序以对整个数据集进行线性排序(在比较中进行衡量)吗?

nd数据集呢?带有比较子集的任意有限数据集?


1
您能问一个更精确的问题吗?您的第一段内容可以理解为您的数据已经排序!您的输入到底是什么,您想要什么输出?
雅克·卡莱特

1
是的,语言有点混乱。我花了一些时间才意识到数据集包含要排序的n个数字,但是这些数字排列在sqrt(n)x sqrt(n)网格中,因此每一行和每一列都已经被排序。这是你的意思吗?

是的,这就是我的意思。为了清楚起见,我将进行编辑。
Zachary Vance 2010年

Answers:


19

很容易证明这个问题的下界是Ω(n 2 log n)(在比较排序模型中):如果位置(i,j)上的元素始终在i + j的1/2范围内,则网格对角线彼此独立,并且每个网格对角线内的排序顺序是任意的。因此,在此约束下,可能的排序总数是对角线长度的阶乘的乘积(在网格的所有对角线上),在n 2 log n中为指数。

也就是说,对于您所描述的有序网格,标准比较排序算法是渐近最优的。


另一个答案给出了具有这种复杂性的显式算法,因此我将考虑针对二维网格解决此问题,而无需实际检查,可能针对任意尺寸的网格解决此问题。
Zachary Vance 2010年

4

如果我正确地理解了该问题(或者我可能不明白,可以告诉我,如果我不知道),您想将2D网格转换为排序的1D数组,而每一行和列都已经在2D网格中进行了排序?

在这种情况下,列表中的第一个元素必须是左上角(根据问题的定义,为(0,0))。在此之后,它必须是(1,0)或(0,1)元素,因为所有其他元素都比定义的要大。

您可以概括地说,网格中的下一个最小元素始终位于已使用元素(或网格边缘)的正下方,也位于已使用元素(或网格边缘)的右侧,因为两者都是定义为小于它。因此,在每次迭代中,您仅需考虑满足此要求的最小值。

您可以在找到候选对象时按排序顺序对其进行排序(一次迭代最多可以使用两个候选对象),并在每次迭代时检查可用的新值(如果有)。如果它们低于先前候选者中的最低者,则立即将其添加到列表中并重复,否则添加先前候选者中的最低者,然后与下一个最低者进行比较,等等。

不幸的是,我没有声称能够提供确切的复杂性,也没有声称它是最有效的,这肯定比幼稚的方法好,并且我希望我对它的解释足够好,让您理解。

编辑:对于像这样的nd网格,我相信同样的基本原理也适用,但是每次迭代最多可以使用n个新的候选对象,此时这些候选对象必须是n个维度中每个维度中最小的未使用元素。


简而言之,您可以执行sqrt(N)方式合并,就像在mergesort中一样?那是我运行得最好的方法,但结果是O(N log N)-我那里没有确切的常数,但是log(sqrt(N))至少有0.5。
Zachary Vance 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.