005【算法篇】随机化快速排序及其时间复杂度

呃,本文有点长……还用到一点点概率论知识

在讲随机化之前,先说下目前大家所熟识的快速排序,先上伪代码:

PARTITION(A,p,r)
  x = A[p]
  i=p
  for j=p+1 to r
    if A[j]<=x
        i=i+1
        A[i]<->A[j]
  A[i]<->A[p]
  return i

最坏情况下的时间复杂度

我们先来分析下最坏情况下的时间复杂度。何为最坏情况?输入的数据已升序或者降序,致使每次划分的时候总有一个子数组中的元素个数为0,而另一个子数组中的元素个数为n-1,由此我们知道此时的时间复杂度为:
T(n)=T(0)+T(n-1)+𝛩(n)\tag{1}
我们根据上一讲的递归树法进行分析,如下图所示:

WechatIMG46.png

故(1)式的时间复杂度计算如下:
\begin{align} T(n)&=T(0)+T(n-1)+𝛩(n)\\ &=T(0)+T(n-1)+cn\\ &=𝛩(\sum^n_{k=1}ck)\\ &=𝛩(n^2) \end{align}

最好情况下的时间复杂度

说完最坏情况,我们再聊最好情况,虽然我们一般不分析这种bogus。最好的情况下是什么样的呢?一般是说每次划分的主元刚好把数组一分为二,两个子数组的元素个数均为n/2,由此其时间复杂度为:
\begin{align} T(n)&=2T(n/2)+𝛩(n)\\ &=𝛩(nlgn) \end{align}
具体过程不证明了,具体可参见上一讲的内容。

综合来说,目前的快速排序其时间复杂度介于上述两种情况之间,也即:
T(n)=𝛰(n^2)=𝛺(nlgn)\tag{2}

由于输入的数据其排序程度我们难以控制,再加上实际工作中大部分情况下输入数据其实已经大致排序,所以使用常规的快速排序将趋于最坏情况下的时间复杂度,这也是我们不想看到的结果,由此下文我们将开始讨论随机化的快速排序。


改变主元位置

由于我们无法控制输入数据的排序程度,又想得到趋近于最好情况的时间复杂度,我们还有什么办法?

既然我们无法控制输入数据,那我们是不是可以尝试下控制每次划分的主元?由于常规的快速排序我们的主元要么在数组的队首或者队尾,如果我们换到其它位置,可不可行?比如针对一组随机输入数据,每次按1:9来划分数组,会有怎么样的时间复杂度?

一般我们的思路是先大胆假设,然后小心论证,如果论证结果确实符合预期,那我们就可以对代码进行改造。话不多说,按刚刚的1:9来划分数组,我们将得到这样一个时间复杂度:
T(n)=T(\frac{1}{10}n)+T(\frac{9}{10}n)+𝛩(n)\tag{3}
这种情况下无法直接使用主定理法,所以我们还是用老朋友递归树法画图如下:

WechatIMG48.png

由此可知:
\begin{align} T(n)&=T(\frac{1}{10}n)+T(\frac{9}{10}n)+𝛩(n)\\ &=𝛩(\sum^{log_{10}n \to log_\frac{10}{9}n}_{k=1}ck)\\ &=𝛰(nlog_\frac{10}{9}n)\\ &\leq 𝛰(nlgn) \end{align}
发现了吗?最坏情况下的时间复杂度开始趋近于𝛰(nlgn)了!由此可以证明,针对随机化的输入数据,改变主元位置能够显著影响时间复杂度。

随机化快速排序

借由上文我们已经很清楚改变主元位置对时间复杂度的影响,那么我们是不是固定一个固定比例的划分就可以了?答案不是的,因为输入的数据存在一定随机性,我们不能保证每次用户提供的数据都是随机排序的,那么第一次按固定比例的划分假设是平衡的,不保证以后每次递归后的划分是平衡的,由此为了在各种输入场景下均保持良好的时间复杂度,我们想到了随机主元位置。

所谓随机主元位置,也即每次划分时的位置随机性选择A[1..n]中的某个位置k,将数组随机机划分为A[1..k-1]和A[k+1..n]两部分。

由于主元位置是随机的,也即每次主元位置的概率是相等的,数理统计中称x~B(0,1),也即0-1分布,由此主元刚好划分到k时的数学期望为:
E[X_k]=\frac{1}{n}\tag{4}
当主元位置随机之后,时间复杂度如何求解?如何验证确实针对任何输入数据情况下,均能有较好的时间复杂度?

当主元位置介于[1..n]之间时,共有n种划分方式,由此我们可以写出随机化下的时间复杂度:
\begin{align} T(n)&= \begin{cases} T(0)+T(n-1)+𝛩(n),\quad当k=1\\ T(1)+T(n-2)+𝛩(n),\quad当k=2\\ ...\\ T(n-1)+T(0)+𝛩(n),\quad当k=n \end{cases}\\\\ &=\sum^n_{k=1}X_k[T(k)+T(n-k-1)+𝛩(n)] \end{align}\tag{5}

由于k的位置是随机的,所以时间复杂度也是随机的,加上随机的机率相同,那么我们只需要利用概率论中的数学期望进行求解即可。

我们对(5)式进一步利用数学期望进行求解,可得如下过程:
\begin{align} E[T(n)]&=E[\sum^n_{k=1}X_k[T(k)+T(n-k-1)+𝛩(n)]]\\ &=\sum^n_{k=1}E[X_k[T(k)+T(n-k-1)+𝛩(n)]]\\ &=\sum^n_{k=1}E[X_k]*E[T(k)+T(n-k-1)+𝛩(n)]\\ &=\frac{1}{n}\sum^n_{k=1}E[T(k)+T(n-k-1)+𝛩(n)]\\ &=\frac{2}{n}\sum^n_{k=1}E[T(k)]+𝛩(n)\\ &...\\\\ &\leq cnlgn,\quad当c>0\tag{6} \end{align}
式(6)最后一步的过程比较艰辛,我不是数学专业的,所以也搞不清楚计算过程,反正就这个么答案……感兴趣的童鞋可以利用上一讲的代换法进行验证(可能要用到微积分,我就不写了)。

由此可知,针对任何输入数组,无论其排序程度如何,随机化的快速排序的时间复杂度为𝛰(cnlgn),趋近于最好情况下的时间复杂度,据说至少三倍速度于常规的快速排序。

最后奉上随机化快速排序的伪代码如下:

RANDOMIZED_PARTITION(A,p,r)
    i=random(p,r)
    A[p]<->A[i]
    return PARTITION(A,p,r)
    
RANDOMIZED_QUICKSORT(A,p,r)
    if p<r
        q=RANDOMIZED_PARTITION(A,p,r)
        RANDOMIZED_QUICKSORT(A,p,q-1)
        RANDOMIZED_QUICKSORT(A,q+1,r)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容