美文网首页
快速排序算法的时间复杂度分析[详解Master method]

快速排序算法的时间复杂度分析[详解Master method]

作者: 高思阳 | 来源:发表于2018-10-18 11:33 被阅读13次

经常听人谈起各种排序算法的时间复杂度,这个是O(n2)的,那个是O(n)的,这些人讲起来可谓滔滔不绝,但是你停下来问问他为什么这个是这个复杂度,他是怎么算出来的?往往没几个人能说出来。这个是一个浮躁的社会,大家都追求速度,到处复制,粘贴代码,拿人家的代码跑一便,就说自己会了这个,会了那个..

也许有人觉得算法分析的太深没有用,但是笔者认为,有时候了解细节很重要,比如快速排序算法的时间复杂度,有时候是O(nlgn), 有时候就是O(n2), 在你不知道自己数据特性的情况下,很难选择是否使用快速排序,因为他并不总是最快的。

说了些没用的,让我们进入正题吧:

为了分析快速排序的时间复杂度,请先看下面的主定理:

主定理: T [n] = aT[n/b] + f (n)

其中 a >= 1 and b > 1 是常量 并且 f (n) 是一个渐近正函数, 为了使用这个主定理,您需要考虑下列三种情况:

想必大家都知道快速排序的过程,如果对这个过程有什么不了解,请参考下文:

http://www.cnblogs.com/pugang/archive/2012/06/27/2565093.html

快速排序的每一次划分把一个 问题分解成两个子问题,其中的关系可以用下式表示:

T[n] = 2T[n/2] + O(n) 其中O(n)为PARTITION()的时间复杂度,这里是分解成两个相等规模的子问题,对比主定理,

T [n] = aT[n/b] + f (n)

我们的快速排序中:a = 2, b = 2, f(n) = O(n)

那么为什么还有最坏情况呢?

考虑如下极端情况,

T[n] = T[n-1] + T[1] + O(n),这里是分解成一个n-1规模的子问题和一个1规模的子问题

问题来了,这一次的划分白玩了,划分之后一边是一个,一边是n-1个,这种极端情况的时间复杂度就是O(n2).

快排代码

+(NSInteger)partition:(NSMutableArray *)arr

{

NSNumber *split = arr.firstObject;

NSInteger i = 0;

NSInteger j = arr.count-1;

while (i!=j) {

while ([arr[j]integerValue]>=split.integerValue) {

j--;

}

while ([arr[i]integerValue]<=split.integerValue) {

i++;

}

if (i>=j) {

break;

}

[self swapeArr:arr index:i andIndex:j];

}

NSNumber *num = arr[j];

arr[j] = split;

arr[0] = num;

return j;

}

+(NSInteger)partition1:(NSMutableArray *)arr

{

NSNumber *firstN = arr.firstObject;

NSInteger i = 0;

NSInteger j = 1;

NSInteger len = arr.count;

while (j<len-1) {

j++;

if ([arr[j]integerValue]<[firstN integerValue]) {

[self swapeArr:arr index:j andIndex:++i];

}

}

[self swapeArr:arr index:i andIndex:0];

return i;

}

快速排序是一个最差时间复杂度为O(n²)的排序算法,这种情况通常出现在选择的轴值(pivot)不能将数组划分为两个长度相等的子数组的时候,比如数组逆序排列的时候,如果选择第一个数作为轴值,划分的子数组的大小分别为0和n-1,此时算法的性能最差。

一个较好的办法是“三数取中”,查看当前数组的第一个、中间一个和最后一个位置的数组,取其中位数,以此来降低轴值选择得不好的可能性。

//将开头、中间、结尾位置的中间一个元素交换到开头

+(void)swap:(NSMutableArray *)arr start:(NSInteger)start end:(NSInteger)end

{

var mid = Math.floor(start+(end-start)/2);

if(this[start]>this[end])

{

this.swap(start,end);

}

if(this[mid]>this[end])

{

this.swap(mid,end);

}

if(this[mid]>this[start])

{

this.swap(mid,start);

}

}

//先进行三数取中,其余地方不变,性能提升非常显著

相关文章

  • 快速排序算法的时间复杂度分析[详解Master method]

    经常听人谈起各种排序算法的时间复杂度,这个是O(n2)的,那个是O(n)的,这些人讲起来可谓滔滔不绝,但是你停下来...

  • 看图说话排序算法之归并排序

    归并排序和快速排序类似,都典型以递归方式实现的算法,归并排序的时间复杂度分析也和快速排序的时间复杂度分析类似。本文...

  • 算法相关

    算法复杂度相关概念:漫画:什么是时间复杂度?算法的时间复杂度和空间复杂度详解算法题库:力扣 一、排序算法 排序算法...

  • 快速排序&快速排序与归并排序的对比

    快速排序算法 快速排序算法是从上到下解决问题使用递归实现,通过巧妙的方式,实现原地排序 分析时间复杂度O(nlog...

  • 算法

    排序算法有哪些?最快的排序算法是哪个?手写一个冒泡排序手写快速排序代码快速排序的过程、时间复杂度、空间复杂度手写堆...

  • 数据结构与算法--排序

    常用的排序算法 如何分析一个“排序算法”? 排序算法的执行效率 最好情况、最坏情况、平均情况时间复杂度 时间复杂度...

  • 13、【排序】快速排序(3)

    6、时间复杂度分析 快速排序算法的时间复杂度一般认为是。简单理解:这个复杂度是一个期望(数学期望)复杂度,因为快速...

  • 算法

    排序算法有哪些? 最快的排序算法是哪个? 手写一个冒泡排序 手写快速排序代码 快速排序的过程、时间复杂度、空间复杂...

  • 排序算法的 时间复杂度 和 空间复杂度

    常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O...

  • 算法

    重拾算法:算法效率分析(一)(空间复杂度和时间复杂度) 详解算法的各种复杂度的差别有多大(带图) 算法复杂度 选择...

网友评论

      本文标题:快速排序算法的时间复杂度分析[详解Master method]

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