O(nlogn)排序之归快速排序

1. 原理

归并排序是不分任何情况直接将数组一分为二。而快速排序是将数组分为一组元素全部小于一个元素v,另一组元素,全部大于这一个元素v。
在这里插入图片描述

排序的时候通常是以第一个元素为基石,来进行递归排序。

package com.fgy.learn;

/**
 * Created by snow_fgy on 2019/4/6.
 */
public class QuickSort1 {


    //获取随机数组
    public int[] getReadom(int n, int random) {

        int [] a = new int[n];
        for (int i = 0; i < n; i++){
            a[i] = (int) (Math.random() * random);
        }
        return a;

    }

    public void quickSort(int [] arr) {
        quickInnerSort(arr, 0, arr.length - 1);

        for (int i: arr) {
            System.out.print(i + " ");
        }
        System.out.println();
    }

    //将arr[l.....r]部分进行快速排序
    public void quickInnerSort(int [] arr, int l, int r) {
        if (l >= r) {
            return;
        }

        int p = partition(arr, l, r);
        quickInnerSort(arr, l, p - 1);
        quickInnerSort(arr, p+1, r);
    }


    //将arr[l...r]进行一次partition操作
    //返回一个p值,满足:arr[l....p-1] < arr[p], arr[p+1 ... r] > arr[p]
    private int partition(int[] arr, int l, int r) {

        //优化:
                int radomIndex = (int) Math.random() * (r - l + 1) + l;
        int temp1 = arr[l];
        arr[l] = arr[radomIndex];
        arr[radomIndex] =  temp1;
        //以第一个元素为基石
        int v = arr[l];


        //arr[l+1...j] < v, arr[j+1...r) > v
        int j = l;
        for (int i = l+1; i <= r; i++) {
            if (arr[i] < v) {
                //进行一次交换操作
                int temp = arr[j+1];
                arr[j+1] = arr[i];
                arr[i] = temp;
                j++;
            }
        }
        //将基石移到该在的位置
        arr[l] = arr[j];
        arr[j] = v;
        return j;
    }


    public static void main(String[] args) {

        QuickSort1 sort = new QuickSort1();
        int[] arr = sort.getReadom(1000 , 10000);

        long time1 = System.currentTimeMillis();
        sort.quickSort(arr);
        long time2 = System.currentTimeMillis();
        System.out.println("selectionSort: " + (time2 - time1) / 1000.0 + "s");
    }
}

优化

  1.高级的排序算法到底层的时候,用插入排序
  2.快排最差的情况是,O(n^2)。随机选择基石,而不是最左侧元素。随机选择数组中的元素,然后和最左侧位置元素交换值。

双路快排:
在这里插入图片描述

private int partition2(int[] arr, int l, int r) {
        int radomIndex = (int) Math.random() * (r - l + 1) + l;
        int temp1 = arr[l];
        arr[l] = arr[radomIndex];
        arr[radomIndex] =  temp1;


        //以第一个元素为基石
        int v = arr[l];
        int i = l+1;
        int j = r;
        while (true){

            while (i <= r && arr[i] < v) {
                i++;
            }
            while (j >= l+1 && arr[j] > v) {
                j--;
            }
            if (i >= j) {
                break;
            }
            int temp = arr[j];
            arr[j] = arr[i];
            arr[i] = temp;
            i++;
            j--;

        }
        //将基石移到该在的位置
        arr[l] = arr[j];
        arr[j] = v;
        return j;
    }

三路快速排序
在这里插入图片描述

    private void quickInnerSort3(int[] arr, int l, int r) {
        if (l >= r) {
            return;
        }


        int radomIndex = (int) Math.random() * (r - l + 1) + l;
        int temp1 = arr[l];
        arr[l] = arr[radomIndex];
        arr[radomIndex] =  temp1;


        //以第一个元素为基石
        int v = arr[l];
        int lt = l;
        int gt = r + 1;
        int i = l+1;
        while (i < gt) {
            if (arr[i] < v) {
                int temp = arr[i];
                arr[i] = arr[lt+1];
                arr[lt+1] = temp;
                lt++;
                i++;
            } else if (arr[i] > v){
                int temp = arr[i];
                arr[i] = arr[gt-1];
                arr[gt-1] = temp;
                gt--;
            } else {
                i++;
            }
        }

        arr[l] = arr[lt];
        arr[lt] = v;

        quickInnerSort3(arr, l, lt-1);
        quickInnerSort3(arr, gt, r);

    }```

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
时间复杂度为O(nlogn)的排序算法有希尔排序,堆排序快速排序和归并排序。其中归并排序是一种稳定的排序算法,而希尔排序、堆排序快速排序是不稳定的排序算法。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python-归并排序算法.docx](https://download.csdn.net/download/qq_43934844/87893705)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [时间复杂度O(nlogn)的排序算法](https://blog.csdn.net/qq_43533956/article/details/123978524)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [时间复杂度为O(nlogn)的排序算法](https://blog.csdn.net/qq_46130027/article/details/129765856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值