排序-快速排序

  • Post author:
  • Post category:其他




分析

快速排序其实跟归并排序有些类似,都需要进行不停的的分组,采取递归的方式进行不停的分。只是其在分的时候,就已经算是在排序了,等合并的时候其实子数组都是已经有序的了

在划分的时候,一般选用原数组中的第一个数据作为分界值,进行划分,在后面的数据与分界值进行比较的时候,小于等于分界值的数,就放在分界值的右边,大于分界值的数放在左边,在不停的分界,知道不能再进行分的时候,就开始将数据进行合并。不过这里需要注意的是,分界值确定以后,右边的数肯定是小于等于分界值的,而左边的数是大于分界值的,相当于我们在排序分界值两边数据的时候,只要两边的数据有序了,合并起来分界值以后肯定也是有序的,所以在分组以后,分界值可以就不包含进去了。

在这里插入图片描述



代码

 /*
     对数组a中从lo到hi之间的元素进行排序
     */
    private static void  sort(Integer[] a,int lo,int hi){
        if (lo>=hi){
            return;
        }
        int partition = partition(a, lo, hi);
        sort(a,lo,partition-1);
        sort(a,partition+1,hi);
    }

   /*
    对数组a中,从索引lo到索引hi之间的元素进行分组,并返回分组界限对应的索引
    */
    private static int partition(Integer[] a, int lo, int hi) {
        int key=a[lo];
        int left=lo;
        int right=hi;
        while (true){
            while (a[right]>key){
                --right;
                if (right==lo){
                    break;
                }
            }
            while (a[left]<=key){

                ++left;
                if (left==hi){
                    break;
                }
            }

            if (left>=right){
                break;
            }else {
                int i = a[left];
                a[left] = a[right];
                a[right] = i;
            }


        }
        int i = a[right];
        a[right] = a[lo];
        a[lo] = i;

        return right;
    }



💫疑问点

自己在开始看视频练习的时候,会很奇怪为什么代码就是在不停的分,之后的合并怎么办呢?但后面发现,虽然每一次是通过递归调用进行在分组,看似好像一次次在切块,但是本质上还是在对原有的数组上进行切分并进行调整排序,每次在变动的是数组中的索引在进行变动,好像是再切分的一样,然后再合并。但实质上其实还是在数组上,而不是像归并排序那样子,每次就切除然后直到不可以切除的时候,然后再对数组进行合并,此时才进行排序。而快排是在自己切分的时候就进行排序了,是一点点把排序大的范围,满满缩减,直到切分到不能再切,而这个时候左边的数肯定大于分界值,右边肯定小于等于分界值这个样子了。即然后分组排完序,有序了,然后加上分界值拼上就肯定也有序了

在这里插入图片描述

在这里插入图片描述



复杂度分析

在这里插入图片描述

在这里插入图片描述



版权声明:本文为qq_46627574原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。