/**
* 特点:一次循环,递归思想
* 思想:
* 1.在数据集中,选择一个元素作为 基准值
* 2.所有小于基准值的元素 在左,所有大于基准值的元素,在右
* 3.对基准的左右两边的两个子集,重复1,2,直到所有子集剩下一个元素为止
*/
public class TestQuickSort {
public static void main(String[] args) {
int[] array = {9, 5, 3, 7, 1};
quickSort(array,0,array.length-1);
for (int i : array) {
System.out.print(i + "\t");
}
}
/**
* 伴随着基准值的移动,会产生一个个小区间--区间不同
* 在这些小区间内的排序操作是同一规模的解决方案---递归--方法
* <p>
* 区间不同,问题规模又一样,那么参数列表必须能够适应变化
* @param a
* @param min
* @param max
* 自己理解的过程中,先写单行注释的内容,出现问题再看【问题】文档注释,以便理解
*/
public static void quickSort(int[] a, int min, int max) {
int i = min,j = max;
//基准值一般都选第一个
int key = a[i];
//第一次循环,循环条件,min<max
while(i<j){
//从后往前比,依此和基准值比较,比基准值小的,则和基准值交换位置,放在基准值的左边
/**问题:
* 在移动的过程中会出现i j 交错过去的情况,也就是数组下标越界
* 故而加限制条件i<j
*/
while(a[j]>=key && i<j ){
j--;
}
if(a[j]<key){
int temp = a[j];
a[j] = key;
key = temp;
}
//基准值交换位置之后,满足,基准值右边的都比基准值大
//那么左边呢?还有没有比基准值大的?是否都比基准值小?
//左边怎么移动?从前往后依此和基准值比较,比基准值大则交换位置
/**问题:
* 在移动的过程中会出现i j 交错过去的情况,也就是数组下标越界
* 故而加限制条件i<j
*/
while(a[i]<=key && i<j){
i++;
}
if(a[i]>key){
int temp = a[i];
a[i] = key;
key = temp;
}
}
/*
* 第一次循环结束,实现了基准值左边都比它小,右边都比它大
* 但不是说就是有序了,还需要对基准值的左右两边进行处理
*/
/**问题:
* 单纯的写
* quickSort(a,min,i-1);
* quickSort(a,i+1,max);
* 会出现堆栈溢出错误,原因在于进行递归调用的时候,没有设置出口,出现了死递归
* 应该设置出口,或者加限制条件
*
* 在i j移动过程中,应该在 min<=i<j<=max 这样一个区间
* 两种方式:
* 1.跳出出口
* if(min>=max) return;
* 2.递归调用加限制条件
* if(i>min) quickSort(a,min,i-1);
* if(j<max) quickSort(a,i+1,max);
*/
if(i>min)
quickSort(a,min,i-1);
if(j<max)
quickSort(a,j+1,max);
}
}
/**总结:
* 代码实现重点关心的问题:
* 1.子集的范围?
* 2.基准值的移动?
* 3.何时结束
*/