/* 说明:以下排序算法将分别对1000、1万、10万、100万个随机数进行排序,记录排序所需时间,并进行比较。VS2017 */
1.冒泡排序法:平均时间复杂度:O(n^2)
#include<iostream>
#include<time.h>
#include<ctime>
using namespace std;
#define MAX 1000
int a[MAX];
//冒泡排序法
void bubble(int a[], int size)
{
int i, temp, work;
for (int pass = 1; pass < size; pass++)
{
work = 1;
for (i = 0; i < size - pass; i++)
if (a[i] > a[i + 1])
{
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
work = 0;
}
if (work) break;
}
}
int main()
{
//随机数
srand((int)time(0));
for (int i = 0; i < MAX; i++)
a[i] = rand() % 100;
//计算时间
clock_t startTime, endTime;
startTime = clock();
bubble(a, MAX);
endTime = clock();
cout << "该次实验的随机数个数为: " << MAX << endl;
cout << "该算法排序所用的时间为: " << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
//输出排序后的数
for (int i = 0; i < MAX; i++)
cout << a[i] << " ";
system("pause");
return 0;
}
总结:比较相邻的元素,如果前者大于后者,则二者交换。一直进行相同的操作,直到最大的元素“浮”到数列的末端。并对所有元素进行相同的步骤,直到排序完成。
1000随机数:时间为0.003s
1万随机数:时间为0.57s
10万随机数:时间为40.224s
100万随机数:时间未知(好几分钟没有结果)
2.归并排序法:平均时间复杂度:O(n*log2n)
#include<iostream>
#include<time.h>
#include<ctime>
using namespace std;
#define MAX 1000
int a[MAX];
//归并排序法
void merge(int arr[], int L, int M, int R)
{
int Left_Size = M - L;
int Right_Size = R - M + 1;
int left[MAX];
int right[MAX];
int i, j, k;
for (i = L; i < M; i++)
{
left[i - L] = arr[i];
}
for (i = M; i <= R; i++)
{
right[i - M] = arr[i];
}
i = 0;
j = 0;
k = L;
while (i < Left_Size && j < Right_Size)
{
if (left[i] < right[j])
{
arr[k] = left[i];
i++;
k++;
}
else
{
arr[k] = right[j];
j++;
k++;
}
}
while (i < Left_Size)
{
arr[k] = left[i];
i++;
k++;
}
while (j < Right_Size)
{
arr[k] = right[j];
j++;
k++;
}
}
void mergeSort(int arr[], int L, int R)
{
if (L == R)
return;
else
{
int M = (L + R) / 2;
mergeSort(arr, L, M);
mergeSort(arr, M + 1, R);
merge(arr, L, M + 1, R);
}
}
int main()
{
//随机数
srand((int)time(0));
for (int i = 0; i < MAX; i++)
a[i] = rand() % 100;
//计算时间
clock_t startTime, endTime;
startTime = clock();
mergeSort(a, 0, MAX-1);
endTime = clock();
cout << "该次实验的随机数个数为:" << MAX << endl;
cout << "该算法排序所用的时间为: " << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
//输出排序后的数
for (int i = 0; i < MAX; i++)
cout << a[i] << " ";
system("pause");
return 0;
}
总结:把长度为n的数组分成两个长度为n/2的数组。对这两个数组分别再采用归并排序。最后将两个排序好的数组合并成一个数组。
1000随机数:时间为0.001s
1万随机数:时间为0.049s
10万随机数:时间为6.908s
100万随机数:时间未知(好几分钟没有结果)
3.快速排序法:平均时间复杂度:O(n*log2n)
#include<iostream>
#include<time.h>
#include<ctime>
using namespace std;
#define MAX 1000
int a[MAX];
//快速排序法
void quick_sort(int left, int right)
{
int l, r;
int t, temp;
if (left > right)
return;
temp = a[left];
l = left;
r = right;
while (l != r)
{
while (a[r] >= temp && l < r)
r--;
while (a[l] <= temp && l < r)
l++;
if (l < r)
{
t = a[l];
a[l] = a[r];
a[r] = t;
}
}
a[left] = a[l];
a[l] = temp;
quick_sort(left, l - 1);
quick_sort(l + 1, right);
}
int main()
{
//随机数
srand((int)time(0));
for (int i = 0; i < MAX; i++)
a[i] = rand() % 100;
//计算时间
clock_t startTime, endTime;
startTime = clock();
quick_sort(1,MAX);
endTime = clock();
cout << "该次实验的随机数个数为: " << MAX << endl;
cout << "该算法排序所用的时间为: " << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
//输出排序后的数
for (int i = 0; i < MAX; i++)
cout << a[i] << " ";
system("pause");
return 0;
}
总结:在数列中选择一个元素作为“基准”。将数列中比基准值小的元素摆放在基准值的前面,将比基准值大的元素放在其后面。然后进行递归,以同样的方法将两个子数列进行排序。
1000随机数:时间为0.001s
1万随机数:时间为0.005s
10万随机数:时间为0.139s
100万随机数:时间为10.624s
4.选择排序法:平均时间复杂度:O(n^2)
#include<iostream>
#include<time.h>
#include<ctime>
using namespace std;
#define MAX 1000
int a[MAX];
//选择排序法
void selection_sort(int a[],int N)
{
int i, j, t, k;
for (i = 0; i < N - 1; i++)
{
k = a[i];
for (j = i + 1; j < N; j++)
if (a[k] > a[j])
k = a[j];
if (k != i)
{
t = a[i];
a[i] = a[k];
a[k] = t;
}
}
}
int main()
{
//随机数
srand((int)time(0));
for (int i = 0; i < MAX; i++)
a[i] = rand() % 100;
//计算时间
clock_t startTime, endTime;
startTime = clock();
selection_sort(a,MAX);
endTime = clock();
cout << "该次实验的随机数个数为: " << MAX << endl;
cout << "该算法排序所用的时间为:" << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
//输出排序后的数
for (int i = 0; i < MAX; i++)
cout << a[i] << " ";
system("pause");
return 0;
}
总结:首先在未排序序列中找到最小的元素,放在数组的首位,然后,从剩余未排序元素中寻找最小元素,找到后放在已排序序列末尾。直到所有元素排列完成。
1000随机数:时间为:0.004s
1万随机数:时间为:0.225s
10万随机数:时间为:34.125s
100万随机数:时间未知(好几分钟没有结果)
5.插入排序法:平均时间复杂度:O(n^2)
#include<iostream>
#include<time.h>
#include<ctime>
using namespace std;
#define MAX 1000
int a[MAX];
//插入排序法
void insert_sort(int a[], int length)
{
int t;
for (int i = 1; i < length; i++)
{
for (int j = i - 1; j >= 0 && a[j + 1] < a[j]; j--)
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
int main()
{
//随机数
srand((int)time(0));
for (int i = 0; i < MAX; i++)
a[i] = rand() % 100;
//计算时间
clock_t startTime, endTime;
startTime = clock();
insert_sort(a, MAX);
endTime = clock();
cout << "该次实验的随机数个数为: " << MAX << endl;
cout << "该算法排序所用的时间为: " << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
//输出排序后的数
for (int i = 0; i < MAX; i++)
cout << a[i] << " ";
system("pause");
return 0;
}
总结:将数组第一个元素认为是有序数组,然后比较第二个元素与第一个元素的大小,有序排列。将数组后面一个元素插入到前面的有序数组中,一直重复至排序完成。
1000个随机数:时间为:0.003s
1万个随机数:时间为:0.195s
10万个随机数:时间为:21.671s
100万个随机数: 时间未知(好几分钟没有结果)
6.希尔排序法:平均时间复杂度:O(n^1.3)
#include<iostream>
#include<time.h>
#include<ctime>
using namespace std;
#define MAX 1000
int a[MAX];
//希尔排序法
void shell_sort(int a[], int n)
{
int gap;
for (gap = 3; gap > 0; gap--)
{
for (int i = 0; i < gap; i++)
{
for (int j = i + gap; j < n; j = j + gap)
{
if (a[j] < a[j - gap])
{
int temp = a[j];
int k = j - gap;
while (k >= 0 && a[k] > temp)
{
a[k + gap] = a[k];
k = k - gap;
}
a[k + gap] = temp;
}
}
}
}
}
int main()
{
//随机数
srand((int)time(0));
for (int i = 0; i < MAX; i++)
a[i] = rand() % 100;
//计算时间
clock_t startTime, endTime;
startTime = clock();
shell_sort(a,MAX);
endTime = clock();
cout << "该次实验的随机数个数为:" << MAX << endl;
cout << "该算法排序所用的时间为:" << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
//输出排序后的数
for (int i = 0; i < MAX; i++)
cout << a[i] << " ";
system("pause");
return 0;
}
总结:希尔排序是插入排序改良的算法,希尔排序步长从大到小调整,第一次循环后面元素逐个和前面元素按间隔步长进行比较并交换,直至步长为1。
1000随机数:时间为:0.001s
1万随机数:时间为:0.051s
10万随机数:时间为:5.253s
100万随机数:时间未知(好几分钟没有结果)
比较总结:
1.对1000个随机数进行排序:
六种排序算法的所需时间均接近0.001s,速度都很快。
2.对1万个随机数进行排序:
快速0.005s < 希尔0.051s < 归并0.049s < 插入0.195s < 选择0.225s < 冒泡0.57s
很明显,快速排序法最快,冒泡排序法最慢。
3.对10万个随机数进行排序:
快速0.139s < 希尔5.253s < 归并6.908s < 插入21.671s < 选择34.125s < 冒泡40.224s
快速排序法最快,冒泡排序法最慢。
4.对100万个随机数进行排序:
快速10.624s,其余算法时间未知,几分钟内排序无法完成。