快速排序算法 Quick sort
2014-10-23 17:14
85 查看
作者:jostree 转载请注明出处 /article/7172699.html
首先随机选择一个轴,并调整数组内各个数字,使得比轴值大的数在轴的右边,比轴小的数在抽的左边。然后在递归的对左边和右边进行快速排序。
在调整的过程中,可以使用交替填坑的算法。
例如对于序列 4 2 3 0 1 5 第一次随机选择轴值为3。那么首先把轴值与第一个数交换。并保存数值3,得到序列:
3 2 4 0 1 5
p q
现在取两个指针p,q分别指向序列的第一个数和最后一个数。即p指向3,q指向5。现在p指向的数字为坑,可以被替换掉,那么另q指向第一个比轴值小且在p后面的数,即1。那么把1覆盖掉p指向的坑。并且另p++,现在序列变为:
1 2 4 0 1 5
p q
现在q指向的1为坑,现在另p找到第一个比轴值3大的且在q之前的数,即4。那么把4填入q指向的坑中。q--,序列变为:
1 2 4 0 4 5
p q
现在p指向的4为坑,把第一个比轴值3小且在p后面的数为0,那么把0填入坑中,p++,序列变为:
1 2 0 0 4 5
q p
现在p指向的0为坑,发现p>q,那么把轴值填入坑中,即完成了partition的过程。最终序列为:
1 2 0 3 4 5 轴值为3,其左侧的数都比3小,右侧的数都比3大。
然后对序列1 2 3和4 5,递归的调用快速排序算法就可以了。
代码如下:
View Code
对于快速排序算法的复杂度我们可以进行如下的计算:
对于一个长度为$n$的序列,我们定义指数函数$I(i,j)$:在快速排序算法中如果第$i$个元素和第$j$个元素比较过就为1否则为0。
那么总的比较次数$X$为:
\begin{equation} X = \sum_{i=1}^{n}\sum_{j=i+1}^{n}I(i,j) \end{equation}
我们可以得到$X$的期望为:
\begin{eqnarray} E(X) &=& E(\sum_{i=1}^{n}\sum_{j=i+1}^{n}I(i,j))\\ &=& \sum_{i=1}^{n}\sum_{j=i+1}^{n}E(I(i,j))\\ &=&\sum_{i=1}^{n}\sum_{j=i+1}^{n}P(\mbox{i is compared with j})\\ &\leq& \sum_{i=1}^{n}\sum_{j=i+1}^{n} \frac{2}{j-i+1}\\ &=&\sum_{i=1}^{n}\sum_{k=1}^{n-i} \frac{2}{k+1}\\ &<& \sum_{i=1}^{n}\sum_{k=1}^{n} \frac{2}{k+1}\\ &=& O(n\log n) \end{eqnarray}
其中第5步,i和j比较的概率,可以这么计算,不妨设i和j分别为排完序后的位置且i<j,那么如果i和j之间的数当过轴,那么i和j在后面的过程中就绝对不会在进行比较。
因此i和j比较过只有可能小于i或大于j的数当做轴,那么在下面的递归过程中,最终会形成一个由i到j组成的序列,i为序列的第一个,j为序列的最后一个,那么i和j比较过只有可能i为轴或j为轴。
其中i为轴的概率为在j-i+1个数中选择1个即1/(j-i+1),同理j被选作为轴的概率也为1/(j-i+1),即i和j被比较过的概率为2/(j-i+1)。
首先随机选择一个轴,并调整数组内各个数字,使得比轴值大的数在轴的右边,比轴小的数在抽的左边。然后在递归的对左边和右边进行快速排序。
在调整的过程中,可以使用交替填坑的算法。
例如对于序列 4 2 3 0 1 5 第一次随机选择轴值为3。那么首先把轴值与第一个数交换。并保存数值3,得到序列:
3 2 4 0 1 5
p q
现在取两个指针p,q分别指向序列的第一个数和最后一个数。即p指向3,q指向5。现在p指向的数字为坑,可以被替换掉,那么另q指向第一个比轴值小且在p后面的数,即1。那么把1覆盖掉p指向的坑。并且另p++,现在序列变为:
1 2 4 0 1 5
p q
现在q指向的1为坑,现在另p找到第一个比轴值3大的且在q之前的数,即4。那么把4填入q指向的坑中。q--,序列变为:
1 2 4 0 4 5
p q
现在p指向的4为坑,把第一个比轴值3小且在p后面的数为0,那么把0填入坑中,p++,序列变为:
1 2 0 0 4 5
q p
现在p指向的0为坑,发现p>q,那么把轴值填入坑中,即完成了partition的过程。最终序列为:
1 2 0 3 4 5 轴值为3,其左侧的数都比3小,右侧的数都比3大。
然后对序列1 2 3和4 5,递归的调用快速排序算法就可以了。
代码如下:
#include <cstdio> #include <cstdlib> #include <iostream> #include <ctime> #include <vector> using namespace std; void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; } int partition(vector<int> &vec, int begin, int end, int pivot) { swap(vec[pivot], vec[begin]); int x = vec[begin]; int p = begin, q = end; while( p < q ) { while( p < q && vec[q] >= x) q--; if( p < q ) vec[p++] = vec[q]; while( p < q && vec[p] < x) p++; if( p < q ) vec[q--] = vec[p]; } vec[p] = x; return p; } void quicksort(vector<int> &vec, int begin, int end) { srand(time(0)); if( begin < end ) { int pivot = rand()%(end-begin+1)+begin; int pos = partition(vec, begin, end, pivot); quicksort(vec, begin, pos-1); quicksort(vec, pos+1, end); } } int main(int argc, char *argv[]) { int n; vector<int> vec; int tmp; while( cin>>n ) { for( int i = 0 ; i < n ; i++ ) { cin>>tmp; vec.push_back(tmp); } quicksort(vec, 0, vec.size()-1); for( int i = 0 ; i < vec.size() ; i++ ) { cout<<vec[i]<<" "; } cout<<endl; } }
View Code
对于快速排序算法的复杂度我们可以进行如下的计算:
对于一个长度为$n$的序列,我们定义指数函数$I(i,j)$:在快速排序算法中如果第$i$个元素和第$j$个元素比较过就为1否则为0。
那么总的比较次数$X$为:
\begin{equation} X = \sum_{i=1}^{n}\sum_{j=i+1}^{n}I(i,j) \end{equation}
我们可以得到$X$的期望为:
\begin{eqnarray} E(X) &=& E(\sum_{i=1}^{n}\sum_{j=i+1}^{n}I(i,j))\\ &=& \sum_{i=1}^{n}\sum_{j=i+1}^{n}E(I(i,j))\\ &=&\sum_{i=1}^{n}\sum_{j=i+1}^{n}P(\mbox{i is compared with j})\\ &\leq& \sum_{i=1}^{n}\sum_{j=i+1}^{n} \frac{2}{j-i+1}\\ &=&\sum_{i=1}^{n}\sum_{k=1}^{n-i} \frac{2}{k+1}\\ &<& \sum_{i=1}^{n}\sum_{k=1}^{n} \frac{2}{k+1}\\ &=& O(n\log n) \end{eqnarray}
其中第5步,i和j比较的概率,可以这么计算,不妨设i和j分别为排完序后的位置且i<j,那么如果i和j之间的数当过轴,那么i和j在后面的过程中就绝对不会在进行比较。
因此i和j比较过只有可能小于i或大于j的数当做轴,那么在下面的递归过程中,最终会形成一个由i到j组成的序列,i为序列的第一个,j为序列的最后一个,那么i和j比较过只有可能i为轴或j为轴。
其中i为轴的概率为在j-i+1个数中选择1个即1/(j-i+1),同理j被选作为轴的概率也为1/(j-i+1),即i和j被比较过的概率为2/(j-i+1)。
相关文章推荐
- 快速排序算法 quick sort 的描述
- 快速排序算法-Quick Sort
- 快速排序算法(Quick Sort)(java)
- Algorithm backup ---- Quick Sort(快速排序算法)
- 快速排序算法(Quick Sort)
- quick sort 快速排序算法
- 快速排序算法的JAVA实现
- 一个简单的冒泡排序和快速排序算法java实现
- “快速排序算法”问题的分而治之算法
- 快速排序 Quick Sort在软考中考查的知识点,转发自NUS
- 快速排序算法原理与实现(一)
- PHP实现插入、选择、冒泡、快速排序算法
- QuickSort - 快速排序算法(C++)
- practical of programming 第二章 java的quick sort
- 快速排序算法
- 快速排序算法
- 适合虚存环境的快速排序算法的性能研究(Performance of Quicksort adapted for virtual memory use)
- 十二之续、快速排序算法的深入分析
- 快速排序算法
- 快速排序算法QuickSort(二)