一、快速排序

1.基本思想:

1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。

2.演示

以一个数组作为示例,取区间第一个数为基准数。

0123456789
7265788604283734885

初始时,i = 0; j = 9; X = a[i] = 72

由于已经将 a[0] 中的数保存到 X 中,可以理解成在数组 a[0] 上挖了个坑,可以将其它数据填充到这来。
从j开始向前找一个比X小或等于X的数。当j=8,符合条件,将a[8]挖出再填到上一个坑a[0]中。a[0]=a[8]; i++; 这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于X的数,当i=3,符合条件,将a[3]挖出再填到上一个坑中a[8]=a[3]; j–;

0123456789
4865788604283738885

然后一直重复这个步骤即可

3.代码

public static void quickSort(int[] arr, int begin, int end) {

        if (begin > end) {
            return ;
        }
        int i = begin;
        int j = end;
        int x = arr[i];
        while (i < j) {
            while (i < j && x < arr[j]) {
                j--;
            }
            if (i < j) {
                arr[i] = arr[j];
            }
            while (i < j && x > arr[i]) {
                i++;
            }
            if (i < j) {
                arr[j] = arr[i];
            }
        }
        arr[i] = x;
        quickSort(arr, begin, i - 1);
        quickSort(arr, i + 1, end);
    }

4.复杂度分析

s
在这里插入图片描述

二、4种优化方式

1.以中枢为基准数据

public static void quickSort(int[] arr, int begin, int end) {
        if (begin > end) {
            return;
        }
        int i = begin;
        int j = end;
        int x = arr[(i + j) / 2];
        int temp = 0;
        while (i < j) {
            while (i < j && x < arr[j]) {
                j--;
            }
            while (i < j && x > arr[i]) {
                i++;
            }
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;

        }
        quickSort(arr, begin, i - 1);
        quickSort(arr, i + 1, end);
    }

2.随机选取基准法

public static void quickSort(int[] arr, int begin, int end) {
        if (begin > end) {
            return ;
        }
        int random = new Random().nextInt(end - begin + 1) + begin; //随机选取基准数
        int i = begin;
        int j = end;
        int x = arr[random];
        int temp = 0;
        while (i < j) {
            while (i < j && x < arr[j]) {
                j--;
            }
            while (i < j && x > arr[i]) {
                i++;
            }
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        quickSort(arr, begin, i - 1);
        quickSort(arr, i + 1, end);
    }

3.三数取中

1.将头部,中部,尾部数据比较大小
2.最大的数据放到最后,最小的数据放到中间,较大的数据放到头部
3.以头部数据为基准值

 public static void newSort(int arr[], int begin, int end) {
        int mid = arr.length /2;
        if (arr[mid] > arr[end]) {
            swap(arr, mid, end);
        }
        if (arr[mid] > arr[begin]) {
            swap(arr, mid, begin);
        }
        if (arr[begin] > arr[end]) {
            swap(arr, begin, end);
        }
    }

    public static void swap(int arr[], int i, int j) {
        int temp = 0;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void quickSort(int arr[], int begin, int end) {
        if (begin >= end) {
            return;
        }
        int i = begin;
        int j = end;
        if (j - i == arr.length - 1) {
            newSort(arr, i, j);
        }

        int x = arr[begin];
        while (i < j) {
            while (i < j && x < arr[j]) {
                j--;
            }
            if (i < j) {
                arr[i] = arr[j];
            }
            while (i < j && x > arr[i]) {
                i++;
            }
            if (i < j) {
                arr[j] = arr[i];
            }
        }
        arr[i] = x;
        quickSort(arr, begin, i - 1);
        quickSort(arr, i + 1, end);
    }

4.序列长度达到一定程度后,使用直插排序

public static void insertSort(int arr[], int i, int j) {
        for (int k = i + 1; k < j + 1; k++) {
            int insertIndex = k;
            int insertValue = arr[k];
            while (insertIndex > 0 && insertValue < arr[insertIndex - 1]) {
                arr[insertIndex] = arr[insertIndex - 1];
                insertIndex--;
            }
            arr[insertIndex] = insertValue;
        }
    }
    public static int quickSort(int arr[], int begin, int end) {
        int i = begin;
        int j = end;
        int x = arr[begin];
        while (i < j) {
            while (i < j && x < arr[j]) {
                j -= 1;
            }
            if (i < j) {
                arr[i] = arr[j];
            }
            while (i < j && arr[i] < x) {
                i += 1;
            }
            if (i < j) {
                arr[j] = arr[i];
            }
        }


        arr[i] = x;
        return i;
    }
    public static void quick_insert(int arr[], int begin, int end) {


        if (end - begin <= 2) {
            insertSort(arr, begin, end);
            return;
        }
        if (begin >= end) {
            return;
        }

        int i = quickSort(arr, begin, end);
        quick_insert(arr, begin, i - 1);
        quick_insert(arr, i + 1, end);
    }
posted on 2021-03-06 20:43  凸凸大军的一员  阅读(289)  评论(0编辑  收藏  举报