金牌模板之快速排序--详解

目录

一:快速排序前言

二:算法思想

三:代码实现


一:快速排序前言

快速排序是一种非常重要的排序算法,入门级算法,它是Tony Hoare在1959年发明的,在1961年公布,它是对冒泡算法的优化,在最坏的情况下,它的算法复杂度是O(n^2),一般复杂度是O(nlogn),大多数情况下是优于O(nlogn)的。它的解释来自《算法艺术与信息学竞赛》:

快速排序的最坏情况是 O(n²)——顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

二:算法思想

随机找取乱序序列中的一个数,一般选取首、尾或者中间数,找完一轮在这个数的左侧都是小于等于它的数,在这个数的右侧都是大于等于这个数的,然后以这个数为分隔点,将原序列分裂为两个子序列,对它的子序列也是如此,每个子序列都是从某个数开始,它的左侧都是小于等与它的,右侧都是大于等于它的数。

X1、X2、X3表示数,a、b、c、d、e、f表示子序列的范围

第一次排序之后,a序列的数都是小于等于X1,b序列的数都是大于等于X1

第二次排序之后,c序列的数都是小于等于X2,d序列的数都是大于等于X2;

                             e序列的数都是小于等于X3,f序列的数都是大于等于X3.

第...........

每次都保证如此,最后排完之后,我们就会得到这样一个结果,任意相邻子序列中的数都会小于等于它右侧序列或右侧相邻子序列中的任何一个数,那原始序列就一定是递增有序序列。

简图如下:

三:代码实现

import java.util.Arrays;
//    快速排序

public class Nov0605 {
    public static void main(String[] args) {
        int[] array = new int[]{1,25,2,1,3,4,5,9,2,1};
        System.out.println("原数组为:" + Arrays.toString(array));
        int index_left = 0;
        int index_right = array.length - 1;
        quicksort(array, index_left, index_right);
        System.out.println("已排序数组:" + Arrays.toString(array));
    }
    
    public static void quicksort(int[] array, int index_left, int index_right) {
        //        当数组中只剩最后一个数的时候退出
        if (index_left >= index_right) {
            return;
        }
//      左指针,右指针,参照数,先从数组两侧,然后用do,while语句,
        int left = index_left-1;
        int right = index_right+1;
        int number = array[(index_left + index_right) / 2];
//        排到剩最后一个数的时候停止,这里不能相等,相等的话数组坐标会出现左溢或者右溢
        while(left < right){
//            每次指针先自加,然后再做判断,这样就与后面的步骤都统一了,所以左指针初始值为-1,右指针为array.length
            do {
                left++;
            } while (array[left] < number);
            do {
                right--;
            } while (array[right] > number);
            if (left < right){
                array[left] += array[right];
                array[right] = array[left] - array[right];
                array[left] -= array[right];
            }
        }
//        此时从right指针所指的数开始,right指针都会停在left指针左边一个,左侧都是小于等于它的,右侧都是大于等于它的
//        排列它的子序列
        quicksort(array, index_left, right);
        quicksort(array, right + 1, index_right);
    }
}

发现有错误请留言,如果喜欢请三连

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值