快速排序法:
与它的名字一样,快速排序法排序速度相比其他排序而言,速度更快。
排序规则:
1.将数组中的一个数据作为基准数据,比基准数小的数据放到基准数前面,比基准数大的放到基准数后面;
2.创建两个坐标,一个坐标从最左边开始,一个坐标从最右边开始;
3.先从右边开始找一个比基准数小的数据,找到之后,坐标停在这个位置;
4.再从左边开始找一个比基准数大的数据,找到之后,坐标也停在这个位置;
5.交换左右坐标中的数据;
6.再重复以上步骤,直到左右两边的坐标相遇;
7.将当前右边坐标中的数据与基准数交换位置;
8.此时,已经完成了第一次排序。左边的数据都比基准数小,右边的数据都比基准数大;
9.分别获取左右两边的数据,并递归执行以上步骤,最终完成整个排序;
下面直接上图,步骤都在图里面:
上代码:
/**
* 快速排序法:
* @author chengxp
*
*/
public class Quick {
/**
* 排序入口
*
* @param arrTarget
* 已被分割的数组
* @param beginIndex
* 被分割数据的开始下标位置
* @param endIndex
* 被分割数据的结束下标位置
*/
public static void entry(int[] arrTarget, int beginIndex, int endIndex) {
//若只有一个数据,不用排序,直接返回
if (beginIndex - endIndex >= 0) {
return;
}
//记录一个坐标,从左边的位置开始
int iIndex = beginIndex;
//记录第二个坐标,从右边的位置开始
int jIndex = endIndex;
//将当前已切割数组中第一个数据作为基准数据
int target = arrTarget[beginIndex];
//当左右两边的数据未相遇前,保持循环
while (iIndex < jIndex) {
//从右边往左边找一个小于/等于基准值的数据,记录当前坐标
while(target < arrTarget[jIndex] && iIndex < jIndex) {
jIndex--;
}
//从左边往右边找一个大于基准值的数据,记录当前坐标
while(target >= arrTarget[iIndex] && iIndex < jIndex) {
iIndex++;
}
//左边和右边的坐标相遇,表示当前数组已完成了排序
if(iIndex >= jIndex) {
break;
}
//将左右两边各自坐标中的数据进行交换
DataProvider.changeEntry(arrTarget, jIndex, iIndex);
System.out.println("changing:" + Arrays.toString(arrTarget));
}
//每次循环完成后,将基准数的数据和右边坐标中的数据进行交换
DataProvider.changeEntry(arrTarget, beginIndex, jIndex);
//继续递归基准数左边的数据
entry(arrTarget, beginIndex, jIndex - 1);
//继续递归基准数右边的数据
entry(arrTarget, jIndex + 1, endIndex);
}
public static void main(String[] args) {
int[] arrTarget = DataProvider.getRandomArray(9);
System.out.println("before:" + Arrays.toString(arrTarget));
Quick.entry(arrTarget, 0, arrTarget.length - 1);
System.out.println("after:" + Arrays.toString(arrTarget));
}
}
输出结果:
before:[56, 99, 51, 43, 87, 55, 37, 6, 29]
changing:[56, 29, 51, 43, 87, 55, 37, 6, 99]
changing:[56, 29, 51, 43, 6, 55, 37, 87, 99]
changing:[37, 29, 6, 43, 51, 55, 56, 87, 99]
after:[6, 29, 37, 43, 51, 55, 56, 87, 99]