这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
前言
上次讲了冒泡排序,相信大家对其都有一定的了解,这次讲一下快速排序。
快速排序是基于冒泡排序的改进版,结合冒泡排序、二分法、递归思想,速度更快,效率更高。适用于数据量较大的数组排序。
思路
简单来说就是先对一段数组进行分割,以其中一个位置上的数据为基准数,左边都是比这个位置上的数据小,右边都是比这个位置上的数据大。这样分为两边后,再分别对这两边的数据进行相同操作,即各自找出一个基准数,然后进行分区,直到之后每个区都只有一个数据时,即递归完成,此时这个数组也就排序完成了。
重点和难点就是如何分区,假定第一个数为基准数,左右两边分别开始遍历,右边从最后一位开始遍历,遇到的第一个比基准数小的数值,令其与基准数对调位置,再来左边从第一位开始遍历,遇到的第一个比基准数大的数值,就让它和基准数继续对调位置,此时右边继续往前找比基准数小的数据,如果有就重复上述动作,直到左右两边指针相遇,这个位置就是基准数的位置,就表示分区已经结束,基准数左边都是比它小的数据,右边都是比它大的数据。
public class Testquick {
public static void quick(int [] arr){
int l = 0;//设定第一个数为基准数,且左边从第一个数开始往右遍历
int h = arr.length - 1; //右边从最后一个数开始往左遍历
quick(arr,l,h); //调用快排方法
}
private static void quick(int[] arr, int l, int h) {
if(l<h){
int index = part(arr,l,h);
//左分区快速排序
quick(arr, l, h-1);
//右分区快速排序
quick(arr, l+1, h);
}
}
private static int part(int[] arr, int l, int h) {
int i= l;
int j = h;
int x = arr[l];//第一个数赋值给基准数x
while(i<j){
//如果右侧遍历到小于x的数据,或者i不小j,则跳出循环
while(arr[j]>=x && i<j){
j--;
}
//如果此时i小于j
if(i<j){
//就将i和j位置上的数据对调,即和基准数位置对调
arr[i] = arr[j];
i++;
}
//如果左侧遍历到大于x的数据,或者i不小j,则跳出循环
while(arr[i] <=x && i<j){
i++;
}
如果此时i小于j
if(i<j){
//就将i和j位置上的数据对调,即和基准数位置对调
arr[j] = arr[i];
j--;
}
}
//最后将基准数赋值到i的位置,即分区完成。
arr[i] = x;
return i;
}
public static void main(String[] args) {
//定义一个无序数组
int arr[] = {11,3,15,65,32,5,8,22,75,29};
quick(arr);
}
}
\