『快速排序的描述』
快排主要是采用了分而治之的思想。
分治模式在每层递归的三个步骤
- 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例;
- 解决这些子问题,递归的求解各子问题。子问题若规模足够小,则直接求解;
- 合并这些子问题的解成原问题的解。
分解:数组A[]被划分两个(可能为空)子数组A[ ]和A[ ],使得A[ ]中的每一个元素都小于等于A[ ],而A[ ]也小于等于A[ ]中的每个元素。其中,计算下标q也是划分过程的一部分。
解决:通过递归调用快速排序,对子数组A[ ]和A[ ]进行排序。
合并:因为子数组都是原址排序的,所以不需要合并操作:数组A[ ]已经有序。
『蒟蒻写的朴素代码』
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n ;
int arr[100010];
void print() {
for(int i =0; i < n; i++) {
if(i == 0)
cout<<arr[i];
else
cout<<" "<<arr[i];
}
}
int pertition(int l,int r) {
int i = l,j = r,base = arr[r];
while(i != j) {
while(i < j && arr[i] <= base ) {
i++;
}
while(i < j && arr[j] >= base ) {
j--;
}
if(i < j)
swap(arr[i],arr[j]);
//print();
}
swap(arr[i],arr[r]);
//print();
//cout<<"\n"<<i++<<"\n";
return i;
}
void quick_sort(int l,int r) {
int p;
if(l <= r) {
p = pertition(l,r);
quick_sort(l,p-1);
quick_sort(p+1,r);
}
}
int main() {
cin>>n;
for(int i = 0 ; i < n; i++) {
scanf("%d",&arr[i]);
}
quick_sort(0,n-1);
print();
return 0;
}
『算法导论中优化后的双向同时探索代码』
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
int arr[100010],n;
void print() {
for(int i =0; i < n; i++) {
if(i == 0)
cout<<arr[i];
else
cout<<" "<<arr[i];
}
}
int pertition(int l,int r) {
int i = l-1,base = arr[r];
for(int j = l; j < r; j++){
if(arr[j] <= base){
i++;
swap(arr[i],arr[j]);
}
}
swap(arr[i+1],arr[r]);
return i+1;
}
void quick_sort(int l,int r) {
if(r < l)
return ;
int p = pertition(l,r);
quick_sort(l,p-1);
quick_sort(p+1,r);
}
int main() {
scanf("%d",&n);
for(int i = 0 ; i < n; i++) {
scanf("%d",arr+i);
}
quick_sort(0,n-1);
print();
return 0;
}
『随机快速排序』
在讨论快速排序的平均情况性能的时候,我们的前提假设是:输入数据的所有排序都是等概率的。但在实际工程中,这个假设的成立条件体现的并不明显,所以我们需要自己引入随机变量的思想,通过使用随机变量的方法,使算法获得一个较好的期望。
这用计算机就很好实现,只需要将A[]和从序列A[]随机选出的一个元素交换,然后再将A[]作为主元即可。因为主元元素是随机选取的,在平均情况下,对输入数组的划分是比较均衡的。
//随机快排
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
int arr[100010],n;
void print() {
for(int i =0; i < n; i++) {
if(i == 0)
cout<<arr[i];
else
cout<<" "<<arr[i];
}
}
int pertition(int l,int r) {
srand((unsigned)time(NULL)); //随机选取arr[p...r]中的一个元素
int random = rand()%(r-l+1) + l;
swap(arr[random],arr[r]);
int i = l-1,base = arr[r];
for(int j = l; j < r; j++){
if(arr[j] <= base){
i++;
swap(arr[i],arr[j]);
}
}
swap(arr[i+1],arr[r]);
return i+1;
}
void quick_sort(int l,int r) {
if(r < l)
return ;
int p = pertition(l,r);
quick_sort(l,p-1);
quick_sort(p+1,r);
}
int main() {
scanf("%d",&n);
for(int i = 0 ; i < n; i++) {
scanf("%d",arr+i);
}
quick_sort(0,n-1);
print();
return 0;
}