我正在为一场比赛做准备并偶然发现了这个问题:考虑一组n个元素,除了一个按顺序出现的元素外,它们被排序。以下哪一项需要O(n)时间?
我的推理如下:
因此我认为它是Heap排序。这个推理是否正确?我想知道我是否遗漏了什么。
答案 0 :(得分:2)
让我们从冒泡排序开始吧。根据我的经验,我使用了大多数资源定义的冒泡排序,其停止条件是在迭代中不执行任何交换(参见例如Wikipedia)。在这种情况下,确实冒泡排序确实会在线性步数之后停止。但是,我记得我偶然发现了描述迭代次数不变的描述,这使得你的情况呈二次方式。因此,关于这个案子我只能说“可能是的” - 这取决于比赛裁判所使用的定义。
关于合并排序和快速排序,你是对的 - 两种算法的经典版本在每个输入上强制执行Θ(n log n)行为。
但是,关于堆排序的推理对我来说似乎不对。在堆排序的典型实现中,堆的构建顺序与所需的最终顺序相反。因此,如果您决定构建一个最小堆,算法的结果将是一个相反的顺序,我猜 - 这不是所需的。另一方面,如果你决定构建一个最大堆,那么堆排序显然会花费大量时间来上下移动元素。
因此,在这种情况下,我会选择冒泡。
答案 1 :(得分:0)
这是一个糟糕的问题,因为你可以猜出哪些答案是假设的是正确的,但它需要做很多假设才能使它实际上正确的问题是无意义的。
如果您对Wikipedia page所示的bubblesort进行编码,那么它将在O(n)中停止,如果那么乱序的元素在其下方的“正确位置”相对于排序迭代。如果它在上面,则它在每次通过时移动不超过一个位置朝向其正确位置。
要在O(n)中无条件地将元素放到正确的位置,你需要一个bubblesort的变体,它可以在每个方向上交替传递。
其他类别的传统实现在近似排序的输入上是O(n log n),但如果你不小心,Quicksort可以是O(n ^ 2)。需要使用Dutch National Flag分区的正确实现来防止不良行为。
Heapsort只花费O(n)时间来构建堆,但是Theta(n log n)时间以排序的顺序从堆中拉出n个项目,每个项目都在Theta(log n)时间内。