澄清“如果使用有序数组实现优先级队列,则插入 - 排序”,为什么“有序”需要?

时间:2012-10-20 04:44:41

标签: sorting data-structures priority-queue insertion-sort

插入排序也适用于无序数组,如示例here所示。由于某些奇怪的原因,标题(或here)中的此语句要求您有一个有序数组来实现插入排序的优先级队列,为什么它有这样的要求?这个Wikipedia -thing here实际意味着什么(下面的截图)?

enter image description here

1 个答案:

答案 0 :(得分:4)

本文讨论了优先级队列的排序用法以及优先级队列的不同实现如何与熟悉的排序算法相对应。

让我们考虑具有操作pop()的ADT优先级队列,其取出由比较函数定义的“最小”元素和将{0}放入优先级队列中的新元素的push()。然后可以通过调用push()将未排序数组中的所有元素推入优先级队列并调用pop()直到优先级队列为空并将弹出的元素放入数组中来完成排序(好吧,你可以定义方法empty()以检查ADT是否为空。)

伪码:

unsorted[]
sorted[]
priority_queue q

foreach element in unsorted
    q.push(element)

i = 0
while !q.empty()
    sorted[i] = q.pop()
    i = i + 1

然后我们讨论如何实现优先级队列。通常,它使用堆有效地实现。但是,没有必要堆 - 你可以用效率较低的方式实现它,如维基百科文章中提到的无序数组或有序数组。只要实现满足push()pop()操作的要求,那就没关系。

对于无序数组,您可以通过将元素直接放在最后一个元素之后来push() - 因为它是无序。当你pop()时,由于数组是无序的,你需要搜索整个数组并选出最大的元素。 (通过将无序数组中的最后一个元素交换到弹出元素的位置,可以轻松地进行删除)。它类似于选择排序,因为您基本上是通过未排序元素列表(位于优先级队列中)并选出要放入排序部分的最大元素。

您可以在此处的push()操作中看到插入排序中的插入操作。

对于有序数组,只需取出第一个元素就可以pop()(通过维护起始索引可以轻松完成删除)。但push()将要求您找出放置元素的位置以维护顺序(因为它是有序数组)。这是与插入排序非常相似的部分,因为您试图将当前元素插入到排序部分(优先级队列实现为有序数组)。

您可以在此处的pop()操作中看到选择排序中的选择操作。