快速排序

我是研究僧i 提交于 2020-02-10 11:37:29

快速排序

  1. 以整个数组为对象执行quickSort
  2. quickSort流程如下
    2.1 通过分割将对象局部数组分割为前后两个局部数组。
    2.2 对前半部分数组执行quickSort。
    2.3 对后半部分数组执行quickSort。
分割

如下图,数组A的分割范围为p ~ r(包含p和r)。这里分割的基准(即A[r],数组的最后一个元素)为x。接下来移动A中的元素,将小于等于 x 的元素移到p ~ i的范围内(包含 i),大于 x 的元素移到i+1 ~ j 的范围内(不包含 j)。其中i初始化为p-1,j初始化为p。
在这里插入图片描述
当A[j]>X时不必移动元素,j直接向前移动,A[j]自动归入i+1 ~ j的组。
在这里插入图片描述
当A[j]≦X时,先让i 向前移动一个位置,然后交换A[j]和A[i]。这样A[j]就归入p ~ i 的组,随着j向后移动,原本位于A[j]的元素又会被归入 i+1 ~ j的组。
在这里插入图片描述
当j和r相遇时,分割结束,将A[i+1]和A[r] 交换,然后X左面的数组都小于等于X,右面的数组都大于X。
代码:

public static void partition(int[] a, int p, int r) {
        int x,i,j,temp;
        x = a[r];
        i = p-1;
        for(j=p;j<r;j++) {
            if(a[j] <= x) {
                i++;
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;   
            }
        }
        temp = a[i+1];
        a[i+1] = a[r];
        a[r] = temp;
    }

分割的算法复杂度为O(n)。

快速排序

快速排序的函数quickSort通过分割将数组一分为二,然后对两个数组递归执行quickSort,从而完成数组的排序。
以A=[13,19,9,5,12,8,7,4,21,2,5,3,14,6,11]为例使用快速排序过程:
在这里插入图片描述
注:红色数字为执行顺序。
代码:

import java.util.Arrays;

public class QuickSort {

    //分割
    public static int partition(int[] a, int p, int r) {
        int x,i,j,temp;
        x = a[r];
        i = p-1;
        for(j=p;j<r;j++) {
            if(a[j] <= x) {
                //先移动i,再交换
                i++;
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;   
            }
        }
        //交换a[i+1]和a[r]
        temp = a[i+1];
        a[i+1] = a[r];
        a[r] = temp;
        //返回基准位置
        return i+1;
    }
    
    public static void quickSort(int[] a, int p, int r) {
        int index;
        if(p<r) {
            index = partition(a,p,r);
            //左半部分数组
            quickSort(a,p,index-1);
            //右边部分数组
            quickSort(a,index+1,r);
        }
    }
    public static void main(String[] args) {
        int[] a = {13,19,9,5,12,8,7,4,21,2,5,3,14,6,11};
        quickSort(a,0,a.length-1);
        System.out.println(Arrays.toString(a));
    }
}

结果:[2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 13, 14, 19, 21]

总结:

  1. 快速排序在分割过程中会交换不相邻元素,所以属于不稳定的排序算法。
  2. 快速排序不需要额外占用内存空间,是一种内部排序(原地排序)。
  3. 如果快速排序分割时恰好选择到中间值,则一共可以分割成log2 n层。每层排序的复杂度为O(n),所以快速排序的平均复杂度为O(nlogn);最坏情况下可以分割为n层,所以最坏复杂度是O(n2)。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!