快速排序


  • 实现思路分析:

    (1)首先设定一个中间值,通过该值将数组分成左右两部分。

    (2)将大于或等于中间值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于中间值,而右边部分中各元素都大于或等于中间值。

    (3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个中间值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。

    (4)使用递归的方法重复上述过程。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了

  • 动图实现:

  • 代码实现:

    package 排序;
    
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;
    
    public class QuickSort {
    
        public static void main(String[] args){
    		//生成长度为八十万的数组
            int[] arr = new int[800000];
            for (int index = 0; index < 8000000; index++) {
                arr[index] = (int)(Math.random() * 800000);
            }
            System.out.println(Arrays.toString(arr));
            //打印开始排序时的时间
            SimpleDateFormat time = new SimpleDateFormat("yyyy:MM:dd:HH:mm:ss");
            System.out.println(time.format(new Date()));
    
            quickSort(arr,0,arr.length-1);
    		//打印排序结束时的时间
            SimpleDateFormat time2 = new SimpleDateFormat("yyyy:MM:dd:HH:mm:ss");
            System.out.println(time2.format(new Date()));
            System.out.println(Arrays.toString(arr));
    
        }
    
        public static void quickSort(int[] arr,int first,int last){
            if (first >= last) {
                return;
            }
    
            int low = first;
            int high = last;
            //如果mid_value = arr[last]的话,下面的两个内部while循环就要换一下顺序
            int mid_value = arr[first]; 
    
    
            while (low < high){
                while (low < high && arr[high] >= mid_value){
                    high-=1;
                }
                arr[low] = arr[high];
    
                while (low < high && arr[low] < mid_value){
                    low +=1;
                }
                arr[high] = arr[low];
            }
            arr[high] = mid_value;
    		//递归对左右两边的数据排序
            quickSort(arr,first,low-1);
            quickSort(arr,low+1,last);
        }
    }
    
  • 性能分析:

    (一)时间复杂度。

    (1)快速排序的一次划分算法从两头交替搜索,直到low和high重合,因此其时间复杂度是O(n)。而整 个快速排序算法的时间复杂度与划分的趟数有关。

    (2)理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过log2n趟划分,便可得到 长度为1的子表。这样,整个算法的时间复杂度为O(nlog2n)。

    (3)最坏的情况是,每次所选的中间数是当前序列中的最大或最小元素,这使得每次划分所得的子表中 一个为空表,另一子表的长度为原表的长度-1。这样,长度为n的数据表的快速排序需要经过n趟划 分,使得整个排序算法的时间复杂度为O(n2)。

    (4)快速排序的平均时间复杂度也是O(nlog2n)。因此,该排序方法被认为是目前最好的一种内部排序 方法。

    (二)空间复杂度:

    (1)快速排序只需要一个元素的辅助空间,但快速排序需要一个栈空间来实现递归。最好的情况下,即快 速排序的每一趟排序都将元素序列均匀地分割成长度相近的两个子表,所需栈的最大深度log2(n+1); 但最坏的情况下,栈的最大深度为n。这样,快速排序的空间复杂度为O(log2n))。

  • 说在最后:

    一直以来都听说快排是最快的内部排序,但是没有一个比较明确而且直观的的数据来说明,直到这次亲自做了测试。上一篇插入排序时提到对80万个数据的排序,插入排序花了2分8秒,选择排序大概花了22分钟左右,而这次的快速排序,花了2秒左右!!!2秒啊???这是什么速度??

    最后,感谢大家的支持(虽然写了也没人看,手动尴尬),但是,,还是要坚持的,不怕慢,怕的是停滞不前。学无止境,加油!!!

posted @ 2020-02-10 13:32  沐雨橙风~~  阅读(478)  评论(0编辑  收藏  举报