快速排序
概念:
快速排序是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
实现:
1、设置一个基准元素;
2、将要排序的数组分割成两部分,小于等于基准元素全部在左边,大于等于基准元素的全在右边。(即确定基准元素在排列好的数组的最终位置);
3、将分割出来的两部分分别进行快速排序,重复1、2步,直至分割出来的元素个数小于2。
示例:
对数组{8,4,3,7,1,5,6,2}进行快排
1、选择要排序的数组的第一个元素为基准元素,将基准元素的值保存起来(挖空部分代表此处的值已没有意义,不是此时的值为空)
int base = num[i];
2、从右边开始逐一查找比基准元素base小的值,找到之后将这个值移到基准元素base的左边
while (base <= num[j] && i < j) {//从右边开始找,在基准数右边找到比它小的数时退出循环
j--;
}
num[i] = num[j];//将找到的比基准小的数移到基准数左边
3、随后再从左边开始逐一查找比基准元素base大的值,找到之后将这个值移到基准元素base的右边
while (base >= num[i] && i < j) { //从左边开始找,在基准数左边找到比它大的数时退出循环
i++;
}
num[j] = num[i];//将找到的比基准大的数移到基准数右边
4、重复2、3步,直至i和j指向同一位置
5、在i和j指向同一位置后,将基准元素base填入该位置,第一次循环结束
将原数组分为两部分再对其递归的进行快速排序,得到最终结果。
quickSort(num, left, i-1);
quickSort(num, i+1, right);
左半边:
右半边:
最终执行结果:
完整代码:
package boke;
import java.util.Arrays;
public class QuickSort {
public static int[] quickSort(int[] num , int left, int right) {
if (left < right) {
int i = left;//左指针
int j = right;//右指针
int base = num[i];
//将所有比基准数小的都移到它的左边,比它大的都移到它的右边
while (i < j) {
while (base <= num[j] && i < j) {//从右边开始找,在基准数右边找到比它小的数时退出循环
j--;
}
num[i] = num[j];//将找到的比基准小的数移到基准数左边
while (base >= num[i] && i < j) { //从左边开始找,在基准数左边找到比它大的数时退出循环
i++;
}
num[j] = num[i];//将找到的比基准大的数移到基准数右边
}
num[i] = base;//最后当i和j指向同一位置时,循环结束,将基准数填入该位置
quickSort(num, left, i-1);
quickSort(num, i+1, right);
}
return num;
}
public static void main(String[] args) {
int num[ ]= {4,8,3,7,1,5,6,2};
System.out.println("原数组为:\n"+Arrays.toString(num));
quickSort(num, 0, num.length-1);
System.out.println("快速排序后:\n"+Arrays.toString(num));
}
}
改进
在这代码中,代码不够简洁,我们可以把确定基准元素下标的操作封装成一个方法,这样可以增加代码的可读性,使得代码更加简洁。
package boke;
import java.util.Arrays;
public class QuickSort2 {
public static int partition(int[] num, int i, int j) {
int base = num[i];
//将所有比基准数小的都移到它的左边,比它大的都移到它的右边
while (i < j) {
while (base <= num[j] && i < j) {//从右边开始找,在基准数右边找到比它小的数时退出循环
j--;
}
num[i] = num[j];//将找到的比基准小的数移到基准数左边
while (base >= num[i] && i < j) { //从左边开始找,在基准数左边找到比它大的数时退出循环
i++;
}
num[j] = num[i];//将找到的比基准大的数移到基准数右边
}
num[i] = base;//最后当i和j指向同一位置时,循环结束,将基准数填入该位置
return i;
}
public static int[] quickSort(int[] num, int left, int right) {
if(left < right) {
int baseIndex = partition(num, left, right);
quickSort(num, left, baseIndex-1);
quickSort(num, baseIndex+1, right);
}
return num;
}
public static void main(String[] args) {
int num[ ]= {4,8,3,7,1,5,6,2};
System.out.println("原数组为:\n"+Arrays.toString(num));
quickSort(num, 0, num.length-1);
System.out.println("快速排序后:\n"+Arrays.toString(num));
}
}