快速排序

1. 基本思想

快速排序是对冒泡排序的一种改进,采用分治法的思想,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序。

2. 排序流程

快速排序算法通过多次比较和交换来实现排序,以从小到大排序为例,其排序流程如下:

  • 定义一个中值(一般是数组第一个元素),通过中值将数组分为两个部分
  • 将小于等于中值的元素集中在数组左半部分,将大于等于中值的元素集中在数组右半部分
  • 即数组的左半部分的值,均小于或等于中值,数组的右半部分的值,均大于或等于中值
  • 此时,又可以将数组的左半部分作为一个新的数组,右半部分也作为一个新的数组,重复上述按中值将数组分为两个部分的过程
  • 可以看出,此过程为递归过程,通过递归先将左半部分排好序,然后将右半部分排好序,即全数组都排好了序
3.排序步骤(图解)

下图只展示第一趟排序的过程,往下每一趟过程都重复此过程,只是数组的边界值发生变化

Java代码如何排队可以插队执行 java代码实现快速排序_java

4.Java代码实现快速排序
4.1函数代码:
public static int[] quickSort(int arr[],int left,int right) {
        int pivot = arr[left];//轴值
        int i = left;//左下标
        int j = right;//右下标
        while (i < j) {
            //在右边找到一个比中值小或者相等的值
            while (i < j && arr[j] > pivot) {
                j--;
            }
            //在左边找到一个比中值大或者相等的值
            while (i < j && arr[i] < pivot) {
                i++;
            }
            //在i和j没有相遇时,如果 arr[i] == arr[j] 此时让i+1
            //即让arr[i+1] 与arr[j]进行交换 ,使两个相同的数在一起
            if (arr[i] == arr[j] && i < j) {
                i++;
            } else {//交换
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }

        //左半部递归
        if (i-1 > left) {
            arr=quickSort(arr,left,i-1);
        }
        //右半部递归
        if (j+1 < right) {
            arr=quickSort(arr,j+1,right);
        }

        return arr;
    }
4.2测试:

测试用例:4,6,1,3,2,5 (与上图用例一致)

public class QuickSort {

    public static void main(String[] args) {
        int[] arr = {4,6,1,3,2,5};

        arr = quickSort(arr, 0, arr.length - 1);
        System.out.println("经过快速排序后的结果为:" + Arrays.toString(arr));
    }
}

测试结果:

Java代码如何排队可以插队执行 java代码实现快速排序_快速排序_02

5.算法分析
  • 时间复杂度
  • 最差:O(N^2),退化为冒泡排序
  • 最优:O(NlogN)
  • 平均:O(NlogN)
  • 空间复杂度
  • 递归调用消耗栈空间,因此为O(logN)
  • 快排是一个不稳定的排序算法
  • 33 33* 排序之后可能会变成 33* 33,即快速排序无法保证相等的元素的相对位置不变