快速排序
2013-07-30 19:34
106 查看
快速排序
参考资料
算法导论
快速排序算法演示
2 解决 通过递归调用快速排序,对子数组 A[ p .. q-1 ] 和 A [ q+1 .. r ] 排序。
3 合并 因为两个子数组是就地排序的,将他们合并并不需要操作,整个数组 A [p .. r] 已排序。
最初调用的是QUICKSORT ( A , 0 , length[ A ] -1 )
PARTITION方法 用来对子数组 A [ p .. r ]进行就地排序。
PARTITION方法写的真是简练巧妙,短短几行代码就实现了数据的分离。
在第3行~第6行中循环的每一轮迭代的开始,对于任何数组下标 k ,有
1 如果 p <= k <= i ,则 A [ k ] <= x
2 如果 i+1 <= k <= j-1 ,则 A [ k ] > x
3 如果 k = r ,则 A [ k ] = x
根据以上3条,可知 i 是一个分界点,i 的左边是小于等于 x 的,i 的右边是大于 x 的。
初始化:p = 0 ,r = 7 ,x = 49 ,i = -1。如下图
![](https://img-blog.csdn.net/20130730193749515?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFpZG91ZmFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第1次循环:j = 0,此时 A [ 0 ] <= x,i = 0, A [ 0 ] 与 A[ 0 ] 交换。如下图
![](https://img-blog.csdn.net/20130730193954296?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFpZG91ZmFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第2次循环:j = 1,此时 A [ 1 ] <= x,i = 1, A [ 1 ] 与 A[ 1 ] 交换。如下图
![](https://img-blog.csdn.net/20130730194155171?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFpZG91ZmFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第3次循环:j = 2,此时 A [ 2 ] > x,i = 1, 不作处理。如下图
第4次循环:j = 3,此时 A [ 3 ] > x,i = 1,不作处理。如下图
![](https://img-blog.csdn.net/20130730190419609?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVzdDExOTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第5次循环:j = 4,此时 A [ 4 ] > x,i = 1,不作处理。如下图
![](https://img-blog.csdn.net/20130730190732250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVzdDExOTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第6次循环:j = 5,此时 A [ 5 ] < x,i = 2,A [ 2 ] 与 A [ 5 ] 交换。如下图
![](https://img-blog.csdn.net/20130730191457093?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVzdDExOTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第6次循环:j = 6,此时 A [ 6 ] < x,i = 3,A [ 3 ] 与 A [ 6 ] 交换。如下图
![](https://img-blog.csdn.net/20130730191753703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVzdDExOTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
最后,j = 7,i = 3,此时循环结束,A[i+1] 与 A[7]交换,于是一趟快排结束。如下图
![](https://img-blog.csdn.net/20130730192351687?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVzdDExOTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
参考资料
算法导论
快排简介
快速排序是一种高效排序算法,对包含 n 个数的输入数组,最坏情况下运行时间为 O ( n2 ),虽然这个最坏情况运行时间比较差,但快速排序算法通常是用于排序的最佳的实用选择,因为其平均性能相当好:期望时间为 O ( n lg n) ,且 O ( n lg n) 记号中隐含的常数因子很小。快排简介
快速排序是一种高效排序算法,对包含 n 个数的输入数组,最坏情况下运行时间为 O ( n2 ),虽然这个最坏情况运行时间比较差,但快速排序算法通常是用于排序的最佳的实用选择,因为其平均性能相当好:期望时间为 O ( n lg n) ,且 O ( n lg n) 记号中隐含的常数因子很小。快排算法思想
快速排序采用了分治的思想。它的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。快速排序算法演示
快速排序算法之3部曲
1 分解 数组 A [ p .. r ] 被划分成两个 ( 可能为空 ) 子数组 A [ p .. q-1 ] 和 A [ q+1 .. r ],使得 A [ p .. q-1 ] 中的每个元素都小于等于 A[ q ] ,A[ q ] 小于等于 A [ q+1 .. r ] 中的元素。2 解决 通过递归调用快速排序,对子数组 A[ p .. q-1 ] 和 A [ q+1 .. r ] 排序。
3 合并 因为两个子数组是就地排序的,将他们合并并不需要操作,整个数组 A [p .. r] 已排序。
快速排序算法伪码
快速排序算法QUICKSORT ( A , p , r ) if p < r then q ← PARTITION ( A , p , r ) QUICKSORT ( A , p , q - 1 ) QUICKSORT ( A , q + 1 , r )
最初调用的是QUICKSORT ( A , 0 , length[ A ] -1 )
PARTITION方法 用来对子数组 A [ p .. r ]进行就地排序。
PARTITION ( A , p , r ) x ← A [ r ] i ← p - 1 for j ← p to r -1 do if A [ j ] <= x then i ← i + 1 exchange A[i ] -- A [ j ] exchange A [i + 1] -- A [ r ] return i + 1
PARTITION方法写的真是简练巧妙,短短几行代码就实现了数据的分离。
在第3行~第6行中循环的每一轮迭代的开始,对于任何数组下标 k ,有
1 如果 p <= k <= i ,则 A [ k ] <= x
2 如果 i+1 <= k <= j-1 ,则 A [ k ] > x
3 如果 k = r ,则 A [ k ] = x
根据以上3条,可知 i 是一个分界点,i 的左边是小于等于 x 的,i 的右边是大于 x 的。
一趟快排
下面通过一组数据来看看 PARTITION 方法是怎么运行的。假设数组 A [ 8 ] = { 49 , 38 , 65 , 97 , 76 , 13 , 27 , 49 }。初始化:p = 0 ,r = 7 ,x = 49 ,i = -1。如下图
第1次循环:j = 0,此时 A [ 0 ] <= x,i = 0, A [ 0 ] 与 A[ 0 ] 交换。如下图
第2次循环:j = 1,此时 A [ 1 ] <= x,i = 1, A [ 1 ] 与 A[ 1 ] 交换。如下图
第3次循环:j = 2,此时 A [ 2 ] > x,i = 1, 不作处理。如下图
第4次循环:j = 3,此时 A [ 3 ] > x,i = 1,不作处理。如下图
第5次循环:j = 4,此时 A [ 4 ] > x,i = 1,不作处理。如下图
第6次循环:j = 5,此时 A [ 5 ] < x,i = 2,A [ 2 ] 与 A [ 5 ] 交换。如下图
第6次循环:j = 6,此时 A [ 6 ] < x,i = 3,A [ 3 ] 与 A [ 6 ] 交换。如下图
最后,j = 7,i = 3,此时循环结束,A[i+1] 与 A[7]交换,于是一趟快排结束。如下图
代码实现
#include <iostream> using namespace std; int partition(int *a , int p , int r) { int x = a[r]; int i = p-1; int tmp; for(int j = p ; j < r; j++) { if( a[j] <= x) //a[i] 与 a[j] 交换 { ++i; tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } tmp = a[i+1]; //a[r+1] 与 a[r] 交换 a[i+1] = x; a[r] = tmp; return i+1; } void quicksort(int *a , int p , int r) { int q ; if( p < r) { q = partition( a , p , r ); quicksort( a , p , q-1); quicksort( a , q+1 , r); } } int main() { int a[8] = {2,1,2,4,7,5,4,8}; quicksort(a,0,7); for(int i = 0; i < 8; i++) cout << a[i] << ' '; cout << endl; }
相关文章推荐
- 快速排序
- [置顶] 深入理解快速排序
- 第七章快速排序之“采取“尾递归”和“三数取中”技术的快速排序”(思考题7-4、7-5)
- 快速排序
- 排序算法总结----快速排序
- 数据结构实验之排序八:快速排序
- 快速排序尾递归版C语言
- 自己写的一个快速排序
- 由快速排序引申的两个分类问题
- QuickSort快速排序
- 数据结构实验之排序八:快速排序
- 快速排序
- 高级排序-快速排序-使用插入排序来处理小于10个数据项的子数组,使快速排序性能发挥到极致。
- PHP 版快速排序
- 算法导论第七章-快速排序-c++
- 快速排序
- 分治与递归之快速排序
- 其他三种排序:堆排序,归并排序,快速排序
- 快速排序的递归和非递归算法
- 快速排序的java版本