快速排序算法是分治算法技术的一个实例,也称为分区交换排序。快速排序采用递归调用对元素进行排序,是基于比较的排序算法中的一个著名算法,也是面试常考的一个算法。
本文主要思想借鉴于这篇文章:
白话经典算法系列之六 快速排序 快速搞定
http://blog.csdn.net/morewindows/article/details/6684558
时间复杂度:
- 时间复杂度:O(nlogn)
- 空间复杂度:O(1)
性能:
假设快速排序的复杂度为T(n) 且所有元素都不相同。T(n) 取决于两个子问题的规模,而规模又取决于中枢点。
- 最好情况:每个划分把数组分成相等的两部分。时间复杂度为(nlogn);
- 最坏情况:每个划分把数组分成不相等的两部分。时间复杂度为(n^2),最坏情况发生在序列已经排序且选择最后一个元素作为中枢点。
- 平均情况下的时间复杂度与最好情况一样也为(nlogn);
基本思想:
书上说该算法主要由以下四步组成:
- 如果数组中仅有一个元素或者没有元素需要排序,则返回。
- 选择数组中的一个元素作为中枢点(通常选择数组最左边的元素)。
- 把数组分成两部分,一部分元素大于中枢点,一部分元素小于中枢点。
- 对两部分数组递归调用该算法。
借鉴参考文章,在这里我们巧妙的把它翻译为这样一种思想:
挖坑填数、分而治之。
操作过程如下:
假设有如下数组,且拟定有一个数组 A[4,6,2,9,1,17] ,下标为index,和两个指针 left 和 right,和一个保存中枢点的变量 temp。
初始时,取第一个元素为中枢点,此时:left = 0; right = 5; temp = A[left] = 4;
由于已经将A[0]中的数保存到temp中,可以理解成在数组A[0]上挖了个坑,可以将其它数据填充到这来。
1、首先从右向左,寻找第一个比temp小的数,准备填充到A[0]的位置上。
当right=4时满足情况,于是将A[4] 挖走,填充到上一个坑A[0]处,并且left++;此时:left=1;right=4;temp=4;形成新坑A[4]。
2、开始从左往右,寻找第一个比temp大的数,准备填充到A[4]的位置上。当left=1时,便满足条件,于是将A[1]挖走,填到上一个坑A[4]处,并且right–;此时:left=1;right=3;temp=4;形成新坑A[1];
3、开始从右往左,寻找第二个比temp小的数,准备填充到A[1]的位置上。
当right=2时满足情况,于是将A[2] 挖走,填充到上一个坑A[1]处,并且left++;此时:left=2;right=2;temp=4;形成新坑A[2]。
4、此时left=right,则第一趟排序结束,将temp填充到中枢点index=2的位置上,可以看到,4的左边都比4小,右边都比4大。
5、得到新的中枢点后,递归对左边和右边重复上述过程即可完成整个排序。
对挖坑填数进行总结(引用自上述参考文章):
1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
2.j–由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
算法实现(java):
|
|
测试程序:
|
|
打印内容如下:
|
|
csdn地址:http://blog.csdn.net/u012534831
github地址:https://github.com/qht1003077897
个人博客地址:https://qht1003077897.github.io
QQ:1003077897