本文使用样本大小为100000大小的随机数据进行排序算法的对比
冒泡排序
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int data[maxn];
int main()
{
srand((unsigned)time(nullptr));
for(int i = 0;i < maxn;i++) data[i] = rand() % 30000;
int st = clock();
for(int i = maxn - 2;i >= 0;i--){
for(int j = 0;j <= i;j++){
if(data[j] > data[j+1])
swap(data[j],data[j+1]);
}
}
printf("用时:%d\n",clock() - st);
return 0;
}
//运行结果
用时:40606
用时40606毫秒
简单插入排序
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int data[maxn];
int main()
{
srand((unsigned)time(nullptr));
for(int i = 0;i < maxn;i++) data[i] = rand() % 30000;
int st = clock();
for(int i = 1;i < maxn;i++){
int j = i,temp = data[i];
while(j && data[j-1] > temp){
data[j] = data[j-1];
j--;
}
data[j] = temp;
}
printf("用时:%d\n",clock() - st);
return 0;
}
//运行结果
用时:4392
用时4392毫秒
归并排序
自己写归并函数
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int data[maxn];
void Merge(int l1,int r1,int l2,int r2){
int i = l1,j = l2;
int temp[maxn],cnt = 0;
while(i <= r1 && j <= r2){
if(data[i] <= data[j]) temp[cnt++] = data[i++];
else temp[cnt++] = data[j++];
}
while(i <= r1) temp[cnt++] = data[i++];
while(j <= r2) temp[cnt++] = data[j++];
for(int i = 0;i < cnt;i++)
data[l1+i] = temp[i];
}
void mergeSort(int left,int right){
if(left < right){
int mid = (left + right) / 2;
mergeSort(left,mid);
mergeSort(mid+1,right);
Merge(left,mid,mid+1,right);
}
}
int main()
{
srand((unsigned)time(nullptr));
for(int i = 0;i < maxn;i++) data[i] = rand() % 30000;
int st = clock();
mergeSort(0,maxn - 1);
printf("用时:%d\n",clock() - st);
return 0;
}
//运行结果
用时:49
用时约为50毫秒
使用库函数merge
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
const int half = maxn / 2;
int data[maxn];
int data1[half];
int data2[half];
int main()
{
srand((unsigned)time(nullptr));
for(int i = 0;i < maxn/2;i++){
data1[i] = rand() % 30000;
data2[i] = rand() % 30000;
}
sort(data1,data1+half);
sort(data2,data2+half);
int st = clock();
merge(data1,data1+half,data2,data2+half,data);
printf("用时:%d",clock() - st);
return 0;
}
//运行结果
用时:0
结果非常残暴,使用了库函数merge的归并排序,运行结果为0。
将数据量变为1000000,即一百万看一下结果
//运行结果
用时:10
残暴残暴,竟然只用了10毫秒
快速排序
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int data[maxn];
int Partition(int left,int right){
int temp = data[left];
while(left < right){
while(left < right && data[right] > temp) right--;
data[left] = data[right];
while(left < right && data[left] <= temp) left++;
data[right] = data[left];
}
data[left] = temp;
return left;
}
void quickSort(int left,int right){
if(left < right){
int pos = Partition(left,right);
quickSort(left,pos-1);
quickSort(pos+1,right);
}
}
int main()
{
srand((unsigned)time(nullptr));
for(int i = 0;i < maxn;i++) data[i] = rand() % 30000;
int st = clock();
quickSort(0,maxn - 1);
printf("用时:%d\n",clock() - st);
return 0;
}
//运行结果
用时:9
运行时间为9毫秒,结果也是非常残暴
修改数据量为一百万
//运行结果
用时:120
可以看到,运行时间为120毫秒。
快速排序确实是快。
随机快排
当然可以使用随机快排优化一下,不总是选择data[left]作为主元,而是先使用随机数在[left,right]范围内随机选一个作为主元。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
int data[maxn];
int Partition(int left,int right){
int p = round(1.0 * rand() / RAND_MAX * (right - left) + left);//生成随机下标
swap(data[p],data[left]);//交换p与left的值
int temp = data[left];
while(left < right){
while(left < right && data[right] > temp) right--;
data[left] = data[right];
while(left < right && data[left] <= temp) left++;
data[right] = data[left];
}
data[left] = temp;
return left;
}
void quickSort(int left,int right){
if(left < right){
int pos = Partition(left,right);
quickSort(left,pos-1);
quickSort(pos+1,right);
}
}
int main()
{
srand((unsigned)time(nullptr));
for(int i = 0;i < maxn;i++) data[i] = rand() % 30000;
int st = clock();
quickSort(0,maxn - 1);
printf("用时:%d\n",clock() - st);
return 0;
}
//运行结果
用时:155
可以看到,数据为1000000的情况下。竟然变慢了。这可能是因为data中的数据是使用随机数生成的,已经够随机了,反而因为在Partition函数中要进行求随机数,而变得慢了。
总结
在数据为100000的前提下
冒泡排序用时:40606毫秒
插入排序用时:4392毫秒
归并排序用时:自己写的归并函数用时49毫秒。使用库函数用时0毫秒
快速排序用时:9毫秒
在数据量为1000000前提下
归并排序用时:使用库函数用时10毫秒,自己写的归并函数跑不出结果,出错
快速排序用时:120毫秒