算法导论之快速排序文档
2016-05-20 16:43
218 查看
对于包含n个数的输入数组来说,快排是一种最坏情况下时间复杂度为O(n*n)的排序算法。虽然最坏时间复杂度很差,但是快排通常是实际排序中的首选,
以为他的平均性能非常好,它的期望时间复杂度为O(nlgn),而且O(nlgn)中隐含的常数因子非常小。
快排分为两个部分的函数来实现:函数QUICKSORT(A,p,r)和函数PARTITION(A,p,r)
函数QUICKSORT(A,p,r)体现的是总的快排的功能,函数的伪代码如下:
QUICKSORT(A,p,r)(A表示的数组名,p是数组的下标,r是数组的上标,即就是对数组A[p,r]进行排序)
QUICKSORT(A,p,r):
If p<r
q=PARTITION(A,p,r);
QUICKSORT(A,p,q-1);
QUICKSORT(A,q+1,r);
看函数的实现过程,其实就是运用了三步分治法进行排序。找到合适的位置,将数组分成两部分,然后对每一部分再次调用此函数,不断重复,直到数组中的元素有序。
另外一个函数PARTITION(A,p,r),此函数的实现体现的正好是快排算法的核心。算法的思想是:以数组的最后一个元素为标杆,每次进行比较和交换,每一轮过后,结果是使得小于等于此元素的所有数组元素被放置在数组的一端,剩下的大于此元素的所有元素被放置在数组的另一端,两端的分界线刚好是原数组的最后一个元素,完成调换过程之后,再对此元素进行调换,将其调换到数组的分界线所处的位置,此时,相当于此元素一遍的元素全都大于此元素,另一边的所有元素都小于此元素,即就实现了排序。
PARTITION(A,p,r)函数的伪代码如下:
PARTITION(A,p,r):
x=A[r];
i=p-1;
for j=p to r-1
if A[j]<=x
i=i+1;
exchange A[i] with A[j];
exchange A[i+1] with A[r];
return i+1;
快排的随机化版本:
在讨论快排的平均情况性能的时候,我们的前提假设是:输入数据的所有排列都是等概率的,但是在实际工程中,这种假设并不总是成立,因此我们可以通过在算法中引入随机性,来使得算法对所有的输入都能获得较好的期望性能。从上面的描述可以看到,每次分成两部分的标准是A[r],即就是要进行排序的这一段数组A[p,r]的最后一个元素的值,很容易可以得到,如果每次分的两部分的长度越相近,最后得到的程序运行时间就越短。但实际工程中的A[r]往往呈现出一种有规律的迹象,因此,我们要对原来的程序稍加改动来实现随机化。
新增加一个函数:RANDOMIZED-PARTITION(A,p,r)
RANDOMIZED-PARTITION(A,p,r)函数的伪代码如下:
RANDOMIZED-PARTITION(A,p,r):
i=RANDOM(p,r); //每次在A[p,r]之间选择一个数来与元素A[r]进行交换
exchange A[r] with A[i];
return PARTITION(A,p,r);
此函数的功能就是每次用产生的随机的值换掉原始的A[r]的值。
此时新的快排不再调用PARTITION,而是调用RANDOMIZED-PARTITION
RANDOMIZED-PARTITION(A,p,r):
If p<r
q=PARTITION(A,p,r);
RANDOMIZED-PARTITION(A,p,q-1);
RANDOMIZED-PARTITION(A,q+1,r);
以为他的平均性能非常好,它的期望时间复杂度为O(nlgn),而且O(nlgn)中隐含的常数因子非常小。
快排分为两个部分的函数来实现:函数QUICKSORT(A,p,r)和函数PARTITION(A,p,r)
函数QUICKSORT(A,p,r)体现的是总的快排的功能,函数的伪代码如下:
QUICKSORT(A,p,r)(A表示的数组名,p是数组的下标,r是数组的上标,即就是对数组A[p,r]进行排序)
QUICKSORT(A,p,r):
If p<r
q=PARTITION(A,p,r);
QUICKSORT(A,p,q-1);
QUICKSORT(A,q+1,r);
看函数的实现过程,其实就是运用了三步分治法进行排序。找到合适的位置,将数组分成两部分,然后对每一部分再次调用此函数,不断重复,直到数组中的元素有序。
另外一个函数PARTITION(A,p,r),此函数的实现体现的正好是快排算法的核心。算法的思想是:以数组的最后一个元素为标杆,每次进行比较和交换,每一轮过后,结果是使得小于等于此元素的所有数组元素被放置在数组的一端,剩下的大于此元素的所有元素被放置在数组的另一端,两端的分界线刚好是原数组的最后一个元素,完成调换过程之后,再对此元素进行调换,将其调换到数组的分界线所处的位置,此时,相当于此元素一遍的元素全都大于此元素,另一边的所有元素都小于此元素,即就实现了排序。
PARTITION(A,p,r)函数的伪代码如下:
PARTITION(A,p,r):
x=A[r];
i=p-1;
for j=p to r-1
if A[j]<=x
i=i+1;
exchange A[i] with A[j];
exchange A[i+1] with A[r];
return i+1;
快排的随机化版本:
在讨论快排的平均情况性能的时候,我们的前提假设是:输入数据的所有排列都是等概率的,但是在实际工程中,这种假设并不总是成立,因此我们可以通过在算法中引入随机性,来使得算法对所有的输入都能获得较好的期望性能。从上面的描述可以看到,每次分成两部分的标准是A[r],即就是要进行排序的这一段数组A[p,r]的最后一个元素的值,很容易可以得到,如果每次分的两部分的长度越相近,最后得到的程序运行时间就越短。但实际工程中的A[r]往往呈现出一种有规律的迹象,因此,我们要对原来的程序稍加改动来实现随机化。
新增加一个函数:RANDOMIZED-PARTITION(A,p,r)
RANDOMIZED-PARTITION(A,p,r)函数的伪代码如下:
RANDOMIZED-PARTITION(A,p,r):
i=RANDOM(p,r); //每次在A[p,r]之间选择一个数来与元素A[r]进行交换
exchange A[r] with A[i];
return PARTITION(A,p,r);
此函数的功能就是每次用产生的随机的值换掉原始的A[r]的值。
此时新的快排不再调用PARTITION,而是调用RANDOMIZED-PARTITION
RANDOMIZED-PARTITION(A,p,r):
If p<r
q=PARTITION(A,p,r);
RANDOMIZED-PARTITION(A,p,q-1);
RANDOMIZED-PARTITION(A,q+1,r);
相关文章推荐
- JavaScript演示排序算法
- 快速排序
- C#快速排序算法实例分析
- 算法之排序算法的算法思想和使用场景总结
- C++快速排序的分析与优化详解
- PHP版本常用的排序算法汇总
- JavaScript实现多种排序算法
- js实现数组冒泡排序、快速排序原理
- php简单实现快速排序的方法
- Java 快速排序(QuickSort)原理及实现代码
- 快速排序和分治排序介绍
- java 算法之快速排序实现代码
- php 地区分类排序算法
- js三种排序算法分享
- Javascript中的常见排序算法
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- Java实现快速排序算法(Quicktsort)
- Java中的数组排序方式(快速排序、冒泡排序、选择排序)
- 快速排序的原理及java代码实现
- 使用Java实现希尔排序算法的简单示例