快速排序

第一节 快速排序
  很久以前就学过快速排序,现在在这里简单的介绍一下吧。
  快速排序是基于分治的一种排序算法,因为是分治思想的,所以它是一种非常快的算法。它的平均运行时间是O(N Log N),最坏的运行时间是O(N^2)。
  算法的基本步骤如下,设S为待排序的集合,n为它的长度:
  1、如果S长度(即n)为1或为0,那么立刻返回。
  2、取S中任意一个元素为枢纽元。
  3、将S分为两个集合:S1和S2,S1中所有元素都小于枢纽元,S2中所有元素都大于枢纽元。
  4、将S1和S2分别再进行一次快速排序。
  快排的思路可能有点难理解,我画几个图来说明吧。


图.1-1 随机选取枢纽元

 


图.1-2 将集合分为两个子集合

 


图.1-3 将两个子集合再进行一次快速排序

  这就是快速排序的核心思想——分治,将一个集合划分成了两个子集合。
  快速排序第二步和第三步整个快速排序的关键,如果没选好方式的话,会影响快排的速度。
第二节 选择枢纽元
  一种错误而使用频率非常广泛的方法:即选取第一个元素做为枢纽元,这有人肯定会说了,很多书上都是使用的第一个元素作为枢纽元啊,为什么说是错误的?但是我在这里就告诉你了,那么你手上的书籍就是一本不够专业的书籍(其实也不一定),说它是错误的是有些夸大,不过考虑到一些特殊的情况,它确实不是一种特别好的选择。考虑一下当使用一个排好序了的或者是逆序的一个集合,那么将会以O(N^2)的时间运行,而程序什么也没做,这难道不是错误吗?有人又要说了这种情况毕竟在少数,我就是不考虑啊。那我告诉你,这种情况确实在少数,但是有更好的办法,就当学习学习吧。如果有人还要说些什么,那我也没话说了。
  一个不错的方法:将枢纽元定义为第一个元素,最后一个元素和位于中间的(即在N/2位置上的)元素的中值。如:2 0 3 6 1 5 9 8 7 4 在这个,在2 4 5之间4即为枢纽元,那么再把2放在第一个元素位置上,5放在最后一个元素位置上,这样可以节省平均时间15s。具体做法如图所示:

图.2-1 选择枢纽元
第三节 分割方式
  具体的分割方式的话,方法很多种,不过我推荐一种方法,先把枢纽元放在集合的最后一个元素的位置上,然后令 i 是集合的第一个位置,j 是上倒数第二个位置(倒数第一是枢纽元),然后 i 向后寻找比枢纽元大的元素再停止,j 向前寻找比枢纽元小的元素再停止,判断是否i < j,如果是,那么交换i 和 j的值,否则就完成了交换,再将枢纽元(最后一个元素)和i 的值进行交换(注意,此时i停止的位置元素必然大于枢纽元。)具体图示:

图.3-1 分割方式1
 

图.3-1 分割方式2
  快速排序我这里就算是讲完了吧,如果还有问题留言问吧。
posted @ 2011-06-09 18:46  zqynux  阅读(513)  评论(0编辑  收藏  举报