您的位置:首页 > 其它

优先级队列与堆排序

2016-06-07 10:33 429 查看
  在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象。最简单的一个例子就是,在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话。在这种情况下,我们的数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue) 。本文首先介绍优先级队列的定义,有序和无序数组以及堆数据结构实现优先级队列,最后介绍了基于优先级队列的堆排序(Heap Sort)

一 定义

  优先级队列和通常的栈和队列一样,只不过里面的每一个元素都有一个"优先级”,在处理的时候,首先处理优先级最高的。如果两个元素具有相同的优先级,则按照他们插入到队列中的先后顺序处理。优先级队列可以通过链表,数组,堆或者其他数据结构实现。

二 实现

  最简单的优先级队列可以通过有序或者无序数组来实现,当要获取最大值的时候,对数组进行查找返回即可。代码实现起来也比较简单,这里就不列出来了。

while (N > 1)
{
Swap(pq, 1, N--);
Sink(pq, 1, N);
}


View Code



  堆排序的动画如下:



分析

  1. 在构建最大堆的时候,最多需要2N次比较和交换

  2. 堆排序最多需要2NlgN次比较和交换操作

  优点:堆排序最显著的优点是,他是就地排序,并且其最坏情况下时间复杂度为NlogN。经典的合并排序不是就地排序,它需要线性长度的额外空间,而快速排序其最坏时间复杂度为N2



  缺点:堆排序对时间和空间都进行了优化,但是:

  1. 其内部循环要比快速排序要长。

  2. 并且其操作在N和N/2之间进行比较和交换,当数组长度比较大的时候,对CPU缓存利用效率比较低。

  3. 非稳定性排序。

四 排序算法的小结

  本文及前面文章介绍了选择排序插入排序希尔排序合并排序快速排序以及本文介绍的堆排序。各排序的稳定性,平均,最坏,最好的时间复杂度如下表:



  可以看到,不同的排序方法有不同的特征,有的速度快,但是不稳定,有的稳定,但是不是就地排序,有的是就地排序,但是最坏情况下时间复杂度不好。那么有没有一种排序能够集合以上所有的需求呢?

五 结语

  本文介绍了二叉堆,以及基于二叉堆的堆排序,他是一种就地的非稳定排序,其最好和平均时间复杂度和快速排序相当,但是最坏情况下的时间复杂度要优于 快速排序。但是由于他对元素的操作通常在N和N/2之间进行,所以对于大的序列来说,两个操作数之间间隔比较远,对CPU缓存利用不太好,故速度没有快速排序快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: