算法之快速排序
2014-04-08 20:32
323 查看
快速排序(Quick Sort):快速排序算法是基于分治策略的另一个排序算法。其基本思想是,对于输入的子数组a[p:r],按以下三个步骤进行排序:
(1)分解(Divide):以a[p]为基准元素将a[p:r]划分成3段a[p:q-1],a[q],和a[q+1:r],使a[p:q-1]中任何一个元素都小于等于a[q],而a[q+1:r]中任何一个元素都大于等于a[q]。下标q在划分过程中确定。
(2)递归求解(Conquer):通过递归调用快速排序算法分别对a[p:q-1]和a[q+1:r]进行排序。
(3)合并(Merge):由于对a[p:q-1]和a[q+1:r]的排序是就地进行的,所以在a[p:q-1]和a[q+1:r]都已排好的序后,不需要执行任何计算,a[p:r]就已排好序。
基于这个思想,可以实现快速排序算法如下:
上述算法中的函数Partition,以一个确定的基准元素a[pivot]对子数组a[l:r](个人比较习惯用l,r)进行划分,它是快速排序算法的关键,代码如下:
我在一些地方安插了输出语句来监测数组以及一些重要变量的变化,读者可以根据这些输出语句,一步一步地理解快排的工作过程。
以下是测试代码:
由于添加了很多辅助理解用的输出语句,结果的输出比较长,就不贴出来了,有兴趣学习快速排序的读者可以把这段代码运行一次,也会有很多收获!
如有不对的地方或对该算法有更好的建议,请指出!
(1)分解(Divide):以a[p]为基准元素将a[p:r]划分成3段a[p:q-1],a[q],和a[q+1:r],使a[p:q-1]中任何一个元素都小于等于a[q],而a[q+1:r]中任何一个元素都大于等于a[q]。下标q在划分过程中确定。
(2)递归求解(Conquer):通过递归调用快速排序算法分别对a[p:q-1]和a[q+1:r]进行排序。
(3)合并(Merge):由于对a[p:q-1]和a[q+1:r]的排序是就地进行的,所以在a[p:q-1]和a[q+1:r]都已排好的序后,不需要执行任何计算,a[p:r]就已排好序。
基于这个思想,可以实现快速排序算法如下:
private static int[] quickSort(int[] a,int l,int r){ if(l < r){ int q = partition(a,l,r); quickSort(a,l,q-1); quickSort(a,q+1,r); } return a; }
上述算法中的函数Partition,以一个确定的基准元素a[pivot]对子数组a[l:r](个人比较习惯用l,r)进行划分,它是快速排序算法的关键,代码如下:
private static int partition(int[] a,int l,int r){ int i = l; int j = r; int pivot = a[l]; int temp; System.out.println("开始时pivot="+pivot); //查看开始时的pivot,非必要 while(true){ while(a[i] <= pivot && i < r) ++i; //i一直向后移动,直到出现a[i]>pivot System.out.println("i="+i); //查看当前的i,非必要 while(a[j] > pivot) --j; //j一直向前移动,直到出现a[j]<pivot System.out.println("j="+j); //查看当前的j,非必要 if(i >= j) break; temp = a[i]; //交换a[i]和a[j] a[i] = a[j]; a[j] = temp; System.out.print("中间过程的数组:"); for(int m:a) System.out.print(m+" "); //输出每次更改为止后的数组,非必要 System.out.println(); } a[l] = a[j]; a[j] = pivot; System.out.println("结束时pivot="+pivot); //查看循环结束时的pivot,非必要 System.out.print("Partition结束后的数组:"); for(int m:a) System.out.print(m+" "); //输出Partition结束后的数组,非必要 System.out.println(); return j; }
我在一些地方安插了输出语句来监测数组以及一些重要变量的变化,读者可以根据这些输出语句,一步一步地理解快排的工作过程。
以下是测试代码:
public static void main(String[] args) { int[] a = {73,12,87,43,25,93,32,26,57,65}; int[] b = quickSort(a,0,a.length-1); for(int i : b) System.out.print(i+" "); }
由于添加了很多辅助理解用的输出语句,结果的输出比较长,就不贴出来了,有兴趣学习快速排序的读者可以把这段代码运行一次,也会有很多收获!
如有不对的地方或对该算法有更好的建议,请指出!
相关文章推荐
- Android自动化测试之Monkeyrunner使用方法及实例
- 存储过程——增删改(二)
- 数据库基础(面试常见题)
- 数据库基础(面试常见题)
- 线性代数(五十二) : 对角化与惯性律
- poj 2251
- 【嵌入式Linux驱动开发】三、字符设备驱动(一)
- jsp面试题
- ac自动机模板
- Monkeyrunner学习之三(如何使用坐标去点击的方法)
- 图论总述
- ubuntu12.04 安装KVM
- 输入一个字符串,如果第二个字符是字母(a~z ,A~Z),则将其大写变小写,小写变大写,如果不是字母则将其修改为空格,并将修改后的字符串输出。
- html+ashx文件上传文件
- [leetCode]Generate Parentheses
- jsp面试题
- jsp面试题
- J2EE面试题集锦(附答案)
- Kmp算法
- xcode更新到5.1,"__curl_rule_01__' declared as an array with a negative size"