每天一个算法之快速排序

165 阅读2分钟

这是我参与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);
        }
    }

\