快排算法的思想用笔画画其实不难理解,但是当我想用代码写出来时发现没那么简单。好久没接触这些基本的知识又忘了,在此做个笔记。我对快排的理解是,从数组的第一个数字开始,每轮确定一个数字的正确位置,当所有数字的位置确定好了,也就排好序了。
比如对 4,1,8,5,3,2,9,10,6,7 这10个数字进行排序,
1.对第一个数字4排序,这里先想一下,当我们把4排好序后它左边的数字应该都比它小,而且它右边的数字应该都比它大,做到这样后4这个数字的位置就排好了。那怎么达到这样的效果呢?
第一步:我们先从数组的右边开始循环,跟4比较大小,如果比4小,那就和4交换位置,循环过程如下:
7>4,不交换
6>4,不交换
10>4,不交换
9>4,不交换
2<4,交换,4和2交换后数组变 2,1,8,5,3,4,9,10,6,7,此次循环到了数组下标为5的位置
第二步:从数组的左边开始循环,跟4比较大小,如果比4大,那就和4交换位置,循环过程如下:
2<4,不交换
1<4,不交换
8>4,交换,8和4交换后数组变为 2,1,4,5,3,8,9,10,6,7,此次循环到了数组下标为2的位置
第三步:这里注意,要左右两边同时循环和4比较大小,直到两边循环相遇。第一步从右向左循环到了下标为5(当前对应数字8)的位置,继续循环过程如下:
3<4,交换,3和4交换后数组变为 2,1,3,5,4,8,9,10,6,7,此次循环到了数组下标为4的位置
第四步:第二步从左向右循环到了下标为2(当前对应数字3)的位置,继续循环过程如下:
5>4,交换,5和4交换后数组变为2,1,3,4,5,8,9,10,6,7,此次循环到了数组下标为3的位置,上一步从右向左也循环到了下标为4的位置,已经相遇了。到此4也已经放到正确的位置了,次轮循环结束。
但是4左边的2,1,3和右边的5,8,9,10,6,7还是乱序的,所以继续对两边的数字重复上面的步骤。
2.对数组的前3个元素2,1,3排序,首先对第一个数字2排序,过程如下:
第一步:从右向左循环和2比较大小
3>2,不交换
1<2,交换,1和2交换后变为1,2,3,此次循环到了数组下标为1的位置,排序已经完成。
3.对数组的后6个元素5,8,9,10,6,7排序,首先对第一个数字5排序,5已经在正确位置上,再继续对后面的5个元素重复上面的步骤循环排序。
public class QuickSort {
/**
* 根据下标交换数组的两个元素
* @param arr 数组
* @param index1 下标1
* @param index2 下标2
*/
public static void swap(int[] arr, int index1, int index2) {
int temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
/**
* 递归循环实现快排
* @param arr 数组
* @param startIndex 快排的开始下标
* @param endIndex 快排的结束下标
*/
public static void quickSort(int[] arr, int startIndex, int endIndex) {
if(arr != null && arr.length > 0) {
int start = startIndex, end = endIndex;
//target是本次循环要排序的元素,每次循环都是确定一个元素的排序位置,这个元素都是开始下标对应的元素
int target = arr[startIndex];
//开始循环,从两头往中间循环,相遇后循环结束
while(start target) {
swap(arr, start, end);
break;
}else {
start++;
}
}
}
//确定target的排序后,如果target左边还有元素,继续递归排序
if((start-1)>startIndex) {
quickSort(arr, startIndex, start-1);
}
//确定target的排序后,如果target右边还有元素,继续递归排序
if((end+1)