我一直在研究快速排序,并发现有时它被称为“确定性快速排序”。
这是正常快速排序的另一个版本吗?正常快速排序和确定性快速排序之间有什么区别?
我一直在研究快速排序,并发现有时它被称为“确定性快速排序”。
这是正常快速排序的另一个版本吗?正常快速排序和确定性快速排序之间有什么区别?
普通(“确定性”)快速排序在特定的数据集上可能表现非常糟糕(例如,对于已排序数据选择第一个未排序元素的实现在时间复杂度上为O(n^2))。
随机化快速排序(选择随机枢轴,而不是确定性选择)有时用于提供更好的预期性能,适用于所有数据集。
快速排序的平均时间复杂度是 O(n log n)
,但最坏情况下会达到 O(n^2)
。这种情况通常发生在选择的枢轴元素始终为最小值或最大值时。
理想情况下,我们希望选择中位数作为枢轴元素。如果直接查找中位数的代价太高(通常是因为你正在尝试使用快速排序),则通常会选择以下两种方法之一:要么选择三个潜在的枢轴元素的中位数,要么随机选择一个元素作为枢轴。
后一种方法使快速排序变得不确定,因为枢轴元素选择过程中存在随机性。
通常情况下,如果一个排序算法每次都能按照相同的顺序排序元素,则被称为“确定性”的。给定一组要按id(升序)排序的记录:
1 Censu
11 Marju
4 Cikku
11 Lonzu
如果使用排序算法,可能会返回Censu、Cikk、Marju、Lonzu或Censu、Cikku、Lonzu、Marju这样的正确排序。确定性排序是一种总是返回相同顺序的排序方式。但这不总是适用的。在快速排序中,如果随机选择枢轴(理想情况下应该选择中位数,但这可能代价高昂),可以获得更快的平均性能。然而,这是有代价的:您的搜索不再是确定性的。
在快速排序中,常见的形容词有确定性和随机化。确定性意味着快速排序始终以相同的方式对相同的数据集进行排序,而随机化快速排序则使用随机化,并且很少以完全相同的方式对相同的数据进行排序(除非数据集非常小 - 那么这种情况更为普遍)。
确定性
关键在于如何选择枢轴。在确定性快速排序中,枢轴的选择是通过选择相同相对位置的枢轴,例如第一个、最后一个或中间元素,或者使用任意数量预定元素的中位数来实现。例如,一种常见的方法是选择第一个、最后一个和中间元素的中位数作为枢轴。即使使用我刚才描述的中值法,某些数据集也很容易产生O(N^2)的时间复杂度。例子是所谓的管风琴数据集:
array = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1]
随机化
随机化快速排序可以选择一个随机的枢轴或使用一些随机选择的枢轴的中位数。仍然存在O(N^2)时间复杂度的可能性,但概率要小得多,并且随着数据集大小的增加而变得更小。
你的源代码可以(而且应该)给出自己的定义,但通常确定性快速排序是通过一个不依赖于随机数的公式选择枢轴。例如,总是选择中间元素或总是选择第一个元素,或类似的方法。这意味着其性能将始终相同(至少在理论上,尽管在实践中差异不应太大),无论您在相同的输入上运行它多少次。随机化快速排序意味着在选择枢轴时使用随机数,这意味着对于相同输入的不同运行无法(轻松地)预测其性能。
这与分区有关(或者是著名的快速排序中使用的分治法中的划分步骤)。如果每次将最后一个(或第一个元素或任何位置的元素,只要在每次划分数据集时使用相同的位置)用作枢轴进行分区,则为确定性快速排序。如果随机选择枢轴,则为随机化快速排序。
这里有一份讲义笔记,可以帮助理解。
希望对您有所帮助。
祝好
除了其他人已经告诉你的关于如何实现确定性快速排序和非确定性快速排序的内容之外,我认为这种排序更重要的一个方面是,在确定性快速排序中,当键冲突时,记录的顺序总是相同的,而在非确定性快速排序中,这些记录的顺序每次运行排序时可能会不同。
我想当您有非唯一键时,不应使用非确定性快速排序。