太自由

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. 快速排序是交换排序的一种,也是对冒泡排序的一种改进,其基本思想是基于分治法的;

2. 快速排序算法的思想是:在待排序表L[1...n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1...k-1], L[k+1...n], 使得L[1...k-1]中所有元素小于pivot, L[k+1...n]中所有元素大于或等于pivot, 则pivot放在了其最终位置L(k)上,这个过程称作一趟快速排序。而后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或为空为止,即所有元素放在了其最终位置上。

3. 通常取待排序表中第一个元素作为枢轴值(基准)对表进行划分,即,必须将待排序表中比枢轴值大的元素向右移动,比枢轴值小的向左移动,使得一趟划分操作之后,表中的元素被枢轴值一分为二。

4. 快速排序的算法性能分析:

(4.1)空间效率:最坏情况为O(n),最好情况为,平均情况为O(log2n);

(4.2)时间复杂度:最坏情况下,时间复杂度为O(n2),平均时间复杂度O(nlog2n);

(4.3)稳定性:不稳定的排序方法;

(4.4)在快速排序算法中,并不产生有序子序列,但每一趟排序后将一个元素(基准元素)放到其最终位置上。

5. 代码

(5.1)交换法

package myleetcode;

import java.util.Arrays;

/**
 * @author sunhongguang
 * @create 2021-03-26-17:29
 */
public class QuickSort {

    public static void main(String[] args) {
        int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
        quickSort(arr, 0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    /**
     *
     * @param arr  待排序数组
     * @param low  待排序数组左边索引
     * @param high 待排序数组右边索引
     */
    public static void quickSort(int[] arr,int low,int high){
        int i,j,temp,t;
        if(low > high){
            return;
        }
        i = low; // 左边哨兵的索引
        j = high; // 右边哨兵的索引
        temp = arr[low]; //temp是基准位,以最左边为基准位
        while(i<j){
            // 从右往左找比基准位小的数
            while(temp <= arr[j] && i<j){
                j--;
            }

            while(temp >= arr[i] && i<j){
                i++;
            }

            if(i<j){
                t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
            }
        }

        // 将基准位与i==j位置处的元素进行交换
        arr[low] = arr[i];
        arr[i] = temp;
        //递归调用,快速排序左边部分
        quickSort(arr, low, j-1);
        //递归调用,快速排序右边部分
        quickSort(arr, j+1, high);
    }
}

结果:

 (5.2) 填坑法(版本1)

 1     // 快速排序-填坑法(版本1)
 2     public static void quickSort_v2(int[] arr, int low, int high) {
 3         if (low < high) {
 4             int i = low;
 5             int j = high;
 6             int temp = arr[low];
 7             while (i < j) {
 8                 while (i < j && temp <= arr[j]) {
 9                     j--;
10                 }
11                 if (i < j) {
12                     arr[i] = arr[j];
13                     i++;
14                 }
15                 while (i < j && temp >= arr[i]) {
16                     i++;
17                 }
18                 if (i < j) {
19                     arr[j] = arr[i];
20                     j--;
21                 }
22             }
23             arr[i] = temp;
24             quickSort_v2(arr, low, i - 1);
25             quickSort_v2(arr, i + 1, high);
26         }
27     }

(5.3)填坑法(版本2)

 1 /**
 2      * 快速排序-填坑法v2
 3      * 
 4      * @param arr
 5      *            待排序数组
 6      * @param low
 7      *            递归排序过程中的起始位置
 8      * @param high
 9      *            递归排序过程中的结束位置
10      */
11     private static void quickSort_v2(int[] arr, int low, int high) {
12         if (low < high) {
13             int index = getIndex(arr, low, high);
14             quickSort_v2(arr, low, index - 1);
15             quickSort_v2(arr, index + 1, high);
16         }
17     }
18 
19     private static int getIndex(int[] arr, int low, int high) {
20         int base = arr[low];
21         while (low < high) {
22             while (low < high && base <= arr[high]) {
23                 high--;
24             }
25             if (low < high) { // 这里的判断可以少进行一次交换
26                 arr[low] = arr[high];
27                 low++;
28             }
29 
30             while (low < high && base >= arr[low]) {
31                 low++;
32             }
33             if (low < high) {
34                 arr[high] = arr[low];
35                 high--;
36             }
37         }
38         arr[low] = base;
39         return low;
40     }

 

 

 

posted on 2021-03-26 22:58  太自由  阅读(163)  评论(0编辑  收藏  举报