快排及常见两种优化方法

作者: 菜头中 | 来源:发表于2017-04-05 14:43 被阅读327次

csdn博客同步发布

正常快排

最近在找实习,然而我觉得博客还是要坚持日更,我相信时间总是挤出来的,不扯淡了,快排这是个面试常考题,今天主要着重于讲他的优化方法,那我就直接先贴快排代码,再来细细道来我所知道的优化方法,正常的快排,先上图片后上代码,比较容易理解


    public void sort(Comparable[] a,int lo,int hi){
        if(lo>= hi) return;
        int j=partition(a,lo, hi);
        sort(a,lo,j-1);
        sort(a,j+1, hi);
    }

    private int partition(Comparable[] a, int lo, int hi) {
     
        int i=lo,j=hi+1;
        Comparable temp = a[lo];
        while(true){
            while(a[++i].compareTo(temp)<0) if(i==hi) break;
            while(a[--j].compareTo(temp)>0) if(i==lo) break;
            if(i>=j) break;//why?why?
            swap(a,i,j);
        }
        swap(a,lo,j);
        return j;
    }

    private void swap(Comparable[] a, int i, int j) {
        Comparable t=a[i];
        a[i]=a[j];
        a[j]=t;
    }

切分轨迹图片如下:

正常快排

时间复杂度

时间复杂度最快平均是O(nlogn),最慢的时候是O(n2);辅助空间也是O(logn);最开始学快排时最疑惑的就是这个东西不知道怎么得来的,一种是通过数学运算可以的出来,还有一种是通过递归树来理解就容易多了


这里写图片描述

这张图片别人博客那里弄过来的,所谓时间复杂度最理想的就是取到中位数情况,那么递归树就是一个完全二叉树,那么树的深度也就是最低为Logn,这个时候每一次又需要n次比较,所以时间复杂度nlogn,当快排为顺序或者逆序时,这个数为一个斜二叉树,深度为n,同样每次需要n次比较,那那么最坏需要n2的时间

第一种优化方法

第一种优化方法,于插入排序相结合,在小数组的情况下,快排比较慢,因为递归sort会出现调用自己情况,所以

//sort里面这句
if(start>=end) return;
//换成下面这句
if(start>=end+M) 
    Insertion.sort(a,start,end);//直接将这部分排序用插入排序来完成
return;

第二种优化方法

第二种就是三向切分,主要用于具有大量重复数据的情况,可以大大提高效率,因为正常的快排会出现同样会把这些数进行递归,

public void sort(Comparable[] a,int lo,int hi){
        if(lo>= hi) return;
        int j=partition(a,lo, hi);
        sort(a,lo,j-1);
        sort(a,j+1, hi);
    }

    private int partition(Comparable[] a, int lo, int hi) {
     
        int i=lo,j=hi+1;
        Comparable temp = a[lo];
        while(true){
            while(a[++i].compareTo(temp)<0) if(i==hi) break;
            while(a[--j].compareTo(temp)>0) if(i==lo) break;
            if(i>=j) break;
            swap(a,i,j);
        }
        swap(a,lo,j);
        return j;
    }

    private void swap(Comparable[] a, int i, int j) {
        Comparable t=a[i];
        a[i]=a[j];
        a[j]=t;
    }

三向切分示意图和切分轨迹图,代码对照着图来看,相信聪明的你很快就可以理解


示意图 切分轨迹图

以上的图主要来自与算法第四版,源码地址[源码地址],(http://download.csdn.net/detail/sinat_28676875/9804063)

ps:如果你觉得我文章哪里写错了或者哪里太糟糕了,欢迎指出
ps:如果你觉得我的文章对你有帮助,那么就点个喜欢,thank you也可以关注我的公众号

我的公众号

相关文章

  • 快排及常见两种优化方法

    csdn博客同步发布 正常快排 最近在找实习,然而我觉得博客还是要坚持日更,我相信时间总是挤出来的,不扯淡了,快排...

  • 快排及优化

    复杂度分析 快排最优的复杂度为o(nlogn)最差时的复杂度为正序或逆序时候,复杂度为o(n^2)因为采用递归,造...

  • 快排

    快排快排优化

  • 快排算法及优化思路

    快排 算法要点 设立基准值,以基准值为中心,根据分治思路把大于基准值放一边,小于基准值放另一边。 递归上一步的操 ...

  • 计算机基础

    数据结构 散列解决冲突的方法有那些? 三种熟悉的排序算法?简述快排过程以及冒泡、插入、快排的区别?以及如何优化快排...

  • 2018-07-13

    快速排序算法 快排普通版本: 快排优化版本: 测试代码:

  • 数据结构:快速排序优化思路

    既然这是一篇主题思想为优化快排的文章,自然就不讨论关于快排的一些定义和基础性的问题,只说快排应该怎么优化。 快排为...

  • iOS 里程计算不准、定位飘(弱信号)的问题解决(做个有深度的a

    目录: 一、问题出现场景 二、常见的计算里程方法1、最土及常见的计算里程方法2、初步优化方案:3、正确的判断/解决...

  • 快排的优化

    0 荷兰国旗 设置两个标志位begin和end分别指向这个数组的开始和末尾,然后用一个标志位current从头开始...

  • CSS布局

    前言 以下将针对CSS常见的居中及布局问题进行讲解,主要以float及对position的两种方法进行讲解。 左右...

网友评论

本文标题:快排及常见两种优化方法

本文链接:https://www.haomeiwen.com/subject/iaatattx.html