算法分析-快速排序QUICK-SORT
示例
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
|
数据
|
6
|
2
|
7
|
3
|
8
|
9
|
|
下标
|
0
|
1
|
2
|
3 |
4
|
5
|
|
数据
|
3
|
2
|
7
|
6
|
8
|
9
|
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
Array.prototype.partition = function (start, end) {
var i = start; //首元素
var j = end; //最后一个元素
var key = this[i]; //设置标兵
var temp;
while (j > i) { //随着j--和i++,必然会相遇,这时候当前小标两边都排好序了
//注意,如果右边换过一次,跳出循环,再从左边开始找。
while (j > i) {
if (this[j] < key) {
temp = this[j];
this[j] = this[i];
this[i] = temp;
break;
} else {
--j;
}
}
while (j > i) {
if (this[i] > key) {
temp = this[i];
this[i] = this[j];
this[j] = temp;
break;
}
++i;
}
}
console.log(i);
console.log(A);
return i;
};
Array.prototype.QUICK_SORT = function (start, end) {
if (end > start) {
var q = this.partition(start, end);
arguments.callee.call(this,start, q - 1);
arguments.callee.call(this,q + 1, end);
}
};
var A = [3, 3, 4, 2,6,3,7,21,734,3265,2,4,60,0];
console.log(A);
A.QUICK_SORT(0, A.length-1);
下面给出算法导论里的伪代码,它的伪代码其实更加优秀:修改的只是partition部分。
先给出伪代码和过程:






下面给出实现代码:
Array.prototype.partition = function (p, r) {
var x = this[r];
var i = p - 1;
for (var j = p; j < r; j++) {
if (this[j] <= x) {
i++;
this.swap(i, j);
}
}
this.swap(i + 1, r);
return i + 1;
};
Array.prototype.swap = function (i, j) {
var temp = this[i];
this[i] = this[j];
this[j] = temp;
};
Array.prototype.QUICK_SORT = function (p, r) {
if (r > p) {
var q = this.partition(p, r);
arguments.callee.call(this, p, q - 1);
arguments.callee.call(this, q + 1, r);
}
};
var A = [3, 3, 4, 2, 6, 3, 7, 21, 734, 3265, 2, 4, 60, 0];
console.log(A);
A.QUICK_SORT(0, A.length - 1);
console.log(A);
这个代码的优势很明显:首先不需要考虑越界了,然后就是循环少了。
下面来探讨它的性能问题:


我们用代换法来证明T(n) = T(n-1)+ T(0) + theta(n) = T(n-1) + theta(n); T(n) = T(n - 1) + theta(n) = theta(n) + theta(n-1) + ... + theta(1) = theta(n^2)


思考:
当数组A的所有元素都具有相同值时,QUICKSORT的时间复杂度是什么?
分析:
当数组A所有元素相同时,QUICKSORT中的划分时极为不平衡的,n-1:0的划分,T(n)=T(n-1)+Θ(n)解这个递归式T(n)=Θ(n^2)
思考:
银行经常会按照交易时间,来记录某一账户的交易情况。但是,很多人却喜欢收到银行对账单是按照支票号码的顺序来排列的。这是因为,人们通常 都是按照支票号码的顺序来开出支票的,而商人也通常都是根据支票编号的顺序兑付支票。这一问题时按照交易时间排序的序列转换成按支票号排序的序列,它是指上是一个对几乎有序的输入序列进行排序的问题。请证明:在这个问题上,INSERTION-SORT的性能往往要优于QUICKSORT?
分析:
插入排序在基本有序的情况下,基本无需移动任何元素来插入,所以只有外层循环了n次,所以时间复杂度为O(n)
快速排序在基本有序的情况下,在划分数组时,划分得非常不平衡,那么其时间复杂度是O(nlgn),而达到完全有序时,时间 复杂度达到O(n^2),所以总之插入排序要优于快速排序。
思考:
假设快速排序的每一层所做的划分的比例都是1-a:a,其中0<a<=1/2且是一个常数。是证明,在相应的递归树中,叶结点的最小深度大约是 -lgn/lga,最大深度大约是-lgn/lg(1-a)(无需考虑整数舍入问题)
分析:
最小深度为每次划分后都是选择最小的一部分继续往下走,每次乘以a。一次迭代减少的元素数从n到an,迭代m次直到剩下的元素为1。
则(a^m)*n = 1, a^m = 1/n,取对数得mlga = -lgn,m = -lgn/lga。
同理可得((1-a)^M)*n = 1,M = -lgn/lg(1-a)。
思考:
试证明:在一个随机输入数组上,对于任何常数0<a<=1/2,PARTITION产生比1-a:a更平衡的划分的概率约为1-2a
证明:
则X+Y=n 那么根据书上根据平衡的定义,X-Y差值越大,比例就越高,那么越不平衡,只有X-Y差值越小,越接近0,X约等于Y的时候 越平衡。
分三种情况讨论:1)当X/n<a时,那么Y/n>1-a, |X-Y|/n>1-2a>0
2)当X/n>1-a时,那么Y<a, |X-Y|/n>1-2a>0
3)当a<X/n<1-a时,那么a<Y<1-a,0<|X-Y|/n<1-2a
只有当|X-Y|/n距离小于一个数时,才可能X-Y差值趋向于0,划分的就越平衡。所以我们选择情况3的这种划分。 在an与(1-a)n之间取X的值,因为划分X落在区间[0,n]上是等可能性的,所以符合均匀分布,落在[an,(1-a)n}]上的任意一点 的概率也是等可能的,所以P{an≤x≤(1-a)n}=((1-a)n-an)/(n-0)=1-2a。得证!


思考:为什么我们分析随机化算法的期望运行时间,而不是其最坏运行时间呢?
分析:随机化算法不能改变最坏情况下得运行时间,但是能降低最坏情况发生的概率。
思考:
在RANDOMIZED-QUICKSORT的运行过程中,在最坏情况下,随机数生成器RANDOM被调用了多少次?在最好情况下呢?
分析:
最好情况是均匀划分,其时间复杂度 T(n)=2T(n/2)+1 =>主定理case1得T(n)=Θ(n)
最坏情况是分成不平衡的划分,其时间复杂度 T(n)=T(n-1)+T(0)+1 各式相加得=>T(n)=Θ(n)




算法分析-快速排序QUICK-SORT的更多相关文章
- 基础排序算法之快速排序(Quick Sort)
快速排序(Quick Sort)同样是使用了分治法的思想,相比于其他的排序方法,它所用到的空间更少,因为其可以实现原地排序.同时如果随机选取中心枢(pivot),它也是一个随机算法.最重要的是,快速排 ...
- [算法] 快速排序 Quick Sort
快速排序(Quick Sort)使用分治法策略. 它的基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分:其中一部分的所有数据都比另外一部分的所有数据都要小.然后,再按此方法对这 ...
- 快速排序Quick sort
快速排序Quick sort 原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归 ...
- Java中的经典算法之快速排序(Quick Sort)
Java中的经典算法之快速排序(Quick Sort) 快速排序的思想 基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小, 然后再按此方法对 ...
- 排序算法 - 快速排序(Quick Sort)
算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). (1) 分治法的基本思想 ...
- quicksort 快速排序 quick sort
* Java基本版 package cn.mediamix; import java.util.LinkedList; public class QuickSort { public static v ...
- 基础算法之快速排序Quick Sort
原理 快速排序(Quicksort)是对冒泡排序的一种改进. 从数列中挑出一个元素,称为"基准"(pivot); 排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的 ...
- 快速排序算法回顾 --冒泡排序Bubble Sort和快速排序Quick Sort(Python实现)
冒泡排序的过程是首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换,然后比较第二个记录和第三个记录的关键字.以此类推,直至第n-1个记录和第n个记录的关键字进行过比较为止 ...
- 快速排序——Quick Sort
基本思想:(分治) 先从数列中取出一个数作为key值: 将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边: 对左右两个小数列重复第二步,直至各区间只有1个数. 辅助理解:挖坑填数 初 ...
- 排序:快速排序Quick Sort
原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序 ...
随机推荐
- java口算器
package dd;import javax.swing.*; import java.awt.*;import java.awt.event.*;class Main extends JFrame ...
- 关于tomcat的远程调试
最近做项目开发发现,在本地运行好好的项目发布到测试服务器既然不好使了,很是郁闷,周围的大神们就给了一条明路:远程调试 查看了网上例子太多了,好像自己真的不会使用,就查了一些简单的资料发现其实很简单 下 ...
- 安装windows7和ubuntu双系统后引导项设置
win7系统,U盘安装ubuntu,在选择[安装启动引导器的设备]时,1.如果你选择的是/dev/sda,即整个硬盘,他会将启动引导器使用grub进行系统引导,而不再使用windows loader, ...
- CentOS6.4 LAMP环境搭建
网上的教程,不能按着抄打进去,这样会打乱你环境放置位置, 会导致配置路径会出问题. 要有一个环境目录优化, 把环境文件都装在/usr/local里面 首先,把安装文件rar都放置在/usr/local ...
- 【转】aiohttp 源码解析之 request 的处理过程
[转自 太阳尚远的博客:http://blog.yeqianfeng.me/2016/04/01/python-yield-expression/] 使用过 python 的 aiohttp 第三方库 ...
- DotNet 资源大全(Awesome最新版)
发表时间:2016-09-20 21:34:58 编辑:机器猫 阅读:136次 目录 API 应用框架(Application Frameworks) 应用模板(Application T ...
- C++14介绍
C++14标准是 ISO/IEC 14882:2014 Information technology -- Programming languages -- C++ 的简称[1] .在标准正式通过之 ...
- Lipschitz连续【zz】
转载地址:http://moosewoler.blog.163.com/blog/static/6986605201242643122296/ 李普希兹连续是以德国数学家Rudolf Lipschit ...
- Google地图轨迹回放模拟
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- linux之SQL语句简明教程---INSERT INTO
到目前为止,我们学到了将如何把资料由表格中取出.但是这些资料是如果进入这些表格的呢? 这就是这一页 (INSERT INTO) 和下一页 (UPDATE) 要讨论的. 基本上,我们有两种作法可以将资料 ...