您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页快速排序Java

快速排序Java

来源:化拓教育网

我们先看图~

换一个例子 

 

 

 

没错
这个流程图,
就是快排的思想
我们把第一个数, 成为key
start寻找比它的数
end寻找比它的数
之后, start与end 进行交换
start>=end, 我们再将 start>=end的位置下标作为下一轮的end,与start

这是hoare法

okk.去写代码吧~~

哎哎哎,但是记得回来~~~ 这种方法,时间复杂度有点高!!!我们要改进一下

import java.util.Arrays;


public class Main {

    public static void main(String[] args) {
        int[] arr = {6,2,9,5,3,7};
        quickSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    private static void quickSort(int[] arr) {
        quick(arr,0,arr.length-1);
    }

    // 分段
    private static void quick(int[] arr, int left, int right) {

        if(left>=right){
            return;
        }
        // pivot是基准
        int pivot = partition(arr,left,right);
        quick(arr,left,pivot-1);
        quick(arr,pivot+1,right);
    }

    // 排序
    private static int partition(int[] arr, int start, int end) {
        int i = start;
        int key = arr[start];
        while (start<end) {
            // key<=arr[end] 要取= 不然会死循环
            while (start<end && key<=arr[end]) {
                end--;
            }
            // key<=arr[end] 要取= 不然会死循环
            while (start<end && key>=arr[start]){
                start++;
            }
            swap(arr,start,end);
        }
        swap(arr,i,start);
        return start;
    }

    private static void swap(int[] arr, int start, int end) {
        int tmp = arr[start];
        arr[start] = arr[end];
        arr[end] = tmp;
    }


}

 okk,我们现在说说有关时间复杂度的问题

在理想情况下,每次都是均分待排序序列 时间复杂度 O(N*logN)
在数组有序或者逆序时, 最慢 O(n^2)
(并且数据太多,递归太深,还会栈溢出)
给你康康图,这里带你推导,这个数是怎么产生的了~~~

 所以,一般情况下,快排使用场景---无序
但是针对有序情况下我们还要进行处理,优化一下~~~

比如--随机选取基准法--三数取中法

介绍一下挖坑法

我们还是先看图

okk, 这就可以根据图, 来写代码了~~~

import java.util.Arrays;

public class Hole {
    public static void main(String[] args) {
        int[] arr = {4,2,9,5,3,7};
        quickSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    private static void quickSort(int[] arr) {
        quick(arr,0,arr.length-1);
    }

    // 分段
    private static void quick(int[] arr, int left, int right) {

        if(left>=right){
            return;
        }
        // pivot是基准
        int pivot = partitionHole(arr,left,right);
        quick(arr,left,pivot-1);
        quick(arr,pivot+1,right);
    }

    // 排序
    private static int partitionHole(int[] arr, int start, int end) {
        int key = arr[start];
        while (start<end) {
            while (start<end && key<=arr[end]) {
                end--;
            }
            arr[start] = arr[end];
            while (start<end && key>=arr[start]){
                start++;
            }
            arr[end] = arr[start];
        }
        arr[start] = key;
        return start;
    }

    private static void swap(int[] arr, int start, int end) {
        int tmp = arr[start];
        arr[start] = arr[end];
        arr[end] = tmp;
    }
}

 我们还有三数取中法, 前后指针法,不递归进行快排,我直接附代码啦~~!!

public static void insertSort2(int[] array,int start, int end){
        for (int i = start; i <= end; i++) {
            int indix = array[i];
            int j = i-1;
            for ( ; j >= start ; j--) {
                if(array[j] > indix){
                    array[j+1] = array[j];
                }else {
                    break;
                }
            }
            array[j+1] = indix;
        }
    }
    private static void quick(int[] arr,int left,int right){
        if(left >= right){
            return;
        }
        if(right-left+1 <= 7){
            insertSort2(arr,left,right);
            return;
        }
        int ret = midNumber(arr,left,right);
        swap(arr,left,ret);
        int pivot = partitionHole(arr,left,right);
        quick(arr,left,pivot-1);
        quick(arr,pivot+1,right);

    }
    private static int midNumber(int[] array, int left, int right){
        int mid = (left+right)/2;
        if(left > right){
            if(mid > left){
                return left;
            }else if(mid < right){
                return right;
            }else {
                return mid;
            }
        }else {
            if(mid > right){
                return right;
            }else if(mid < left){
                return left;
            }else {
                return mid;
            }
        }
    }
    public static void quickSort(int[] arr){
        quick(arr,0,arr.length-1);
    }
//指针法
    private static int partition(int[] arr,int start,int end){
        int k = arr[start];
        int pre = start;
        int cur = start+1;
        while(cur < end){
            while (arr[cur]<k && arr[++pre] != arr[cur]){
                swap(arr,pre,cur);
            }
            cur++;
        }
        swap(arr,pre,start);
        return pre;
    }
//非递归的快速排序
    private static int partitionHole1(int[] arr,int start,int end){
        int tmp = arr[start];
        while (start<end){
            while (start<end && arr[end] >= tmp){
                end--;
            }
            arr[start] = arr[end];
            while (start<end && arr[start] <= tmp){
                start++;
            }
            arr[end] = arr[start];
        }
        arr[start] = tmp;
        return start;
    }
    private static void quick1(int[] arr,int left,int right){
        Stack<Integer> stack = new Stack<>();
        int pivot = partitionHole1(arr,left,right);

        if(pivot > left+1) {
            stack.push(left);
            stack.push(pivot - 1);
        }
        if(pivot < right-1) {
            stack.push(pivot + 1);
            stack.push(right);
        }

        while(!stack.empty()){
            right = stack.pop();
            left = stack.pop();
            pivot = partitionHole1(arr,left,right);
            if(pivot > left+1) {
                stack.push(left);
                stack.push(pivot - 1);
            }
            if(pivot < right-1) {
                stack.push(pivot + 1);
                stack.push(right);
            }
        }
    }
    public static void quickSort1(int[] arr){
        quick1(arr,0,arr.length-1);
    }

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务