目录
一、要求
(一)目的
1.熟悉算法设计的基本思想
2.掌握排序算法的基本思想,并且能够分析算法性能
(二)内容与设计思想
- 设计一个数据生成器,输入参数包括N, s, t, T;可随机生成一个大小为N、数值范围在[s, t]之间、类型为T的数据集合;T包括三种类型(顺序递增、顺序递减、随机取值)
- 编程实现merge sort(归并排序)算法和insertion sort(插入排序)算法。(以下测试都使用第1步的数据生成器)
- 对于顺序递增类型的数据集合而言,在不同数据规模情况下(数据规模为10^2, 10^3, 10^4, 10^5, 10^6)下,两种算法的运行时间各是多少?
- 对于顺序递减类型的数据集合而言,在不同数据规模情况下(数据规模为10^2, 10^3, 10^4, 10^5, 10^6)下,两种算法的运行时间各是多少?
- 对于随机取值类型的数据集合而言,在不同数据规模情况下(数据规模为10^2, 10^3, 10^4, 10^5, 10^6)下,两种算法的运行时间各是多少?
补充题:编程实现bubble sort 算法,并与上面两个算法进行对比。
(三)实验过程
- 写出数据生成器和三种算法的源代码;
- 分别画出各个实验报告的折线图
二、代码
(一)数据生成器
#include<iostream>
using namespace std;
int main(){
int N,s,t;
cin >> N;
cin >> s;
cin >> t;
int arr[N];
for(int i=0;i<N;i++){
arr[i]=(rand()%(t-s+1))+s;
}
return 0;
}
T包括三种类型:顺序递增、顺序递减和随机取值
顺序递增、顺序递减通过sort函数实现
以T2顺序递减为例:
decline.cpp
#include<iostream>
#include<algorithm>//sort函数
using namespace std;
int decline(int arr[],int N){
sort(arr, arr + N, greater<int>());//从大到小排列
//sort(arr, arr + N);//从小到大排列
for(int i = 0;i < N;i++){
cout << arr[i] << " ";
}
return 0;
}
*数据生成器调用外部文件中的函数,添加#include <rise.cpp>
(二)算法(以T2为例)
1.merge sort(归并排序)算法
#include<iostream>
#include<algorithm>
using namespace std;
void merge(int *data,int start,int end,int *result)
{
int left_length = (end - start + 1) / 2 + 1;
int left_index = start;
int right_index = start + left_length;
int result_index = start;
while(left_index<start + left_length && right_index <end + 1) //store data into new array
{
if(data[left_index] <= data[right_index])
result[result_index++] = data[left_index++];
else
result[result_index++] = data[right_index++];
}
while(left_index < start + left_length)
result[result_index++] = data[left_index++];
while(right_index <end+1)
result[result_index++] = data[right_index++];
}
void merge_sort(int *data,int start,int end,int *result)
{
if(1 == end - start) //last only two elements
{
if(data[start] > data[end])
{
int temp = data[start];
data[start] = data[end];
data[end] = temp;
}
return;
}
else if (end == start)
return; //last one element then there is no need to sort;
else{
//continue to divide the interval
merge_sort(data, start, (end - start + 1) / 2 + start, result);
merge_sort(data, (end - start + 1) / 2 + start + 1, end, result);
//start to merge sorted data
merge(data, start, end, result);
for (int i = start; i <= end;++i)
{
data[i] = result[i];
}
}
}
//example
int MergeSort(int data[],int length)
{
int result[length];
merge_sort(data, 0, length - 1, result);
for (int i = 0; i < length;i++)
cout << result[i]<<' ';
return 0;
}
2.insertion sort(插入排序)算法
#include<iostream>
using namespace std;
int InsertSort(int a[],int N){
for(int j=1;j<N;j++){
int key = a[j];
int i=j-1;
while(i>=0&&key>a[i]){
a[i+1]=a[i];
i--;
}
a[i+1]=key;
}
for(int i = 0;i < N;i++){
cout << a[i] << " ";
}
return 0;
}
3.bubble sort (冒泡排序)算法
#include<iostream>
using namespace std;
void BubbleSort(int a[], int n)
{
for (int i = 1; i < n; i++)
{
for (int j = 0; j < n - i; j++)
{
if (a[j + 1] < a[j])
{
int x = a[j];
a[j] = a[j + 1];
a[j + 1] = x;
}
}
}
for(int i=0;i<n;i++){
cout << a[i] << " ";
}
}
(三)时间测试(以T2为例)
数据规模即N=10^2,10^3,10^4……
#include<iostream>
#include <chrono>
#include <iostream>
#include <iomanip>
#include <time.h>
#include "decline.cpp"
#include "de_merge sort.cpp"
#include "de_insertion sort.cpp"
#include "de_bubble sort.cpp"
using namespace std;
double test_1(int arr[],int N){
auto start = std::chrono::high_resolution_clock::now(); // test part
MergeSort(arr,N);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
std::cout << std::fixed << std::setprecision(10) << diff.count() << std::endl;
return diff.count();
}
double test_2(int arr[],int N){
double start = clock(); // test part
InsertSort(arr,N);
double end = clock();
double diff = (end - start) / CLOCKS_PER_SEC; // C 风格时间测量的精度为 1 毫秒
printf("%.10f\n", diff);
return diff;
}
double test_3(int arr[],int N){
double start = clock(); // test part
BubbleSort(arr,N);
double end = clock();
double diff = (end - start) / CLOCKS_PER_SEC;
printf("%.10f\n", diff);
return diff;
}
int main(){
int N,s,t;
N=100;
s=1;
t=10000;
int arr[N];
for(int i=0;i<N;i++){
arr[i]=(rand()%(t-s+1))+s;
}
decline(arr,N);
cout << endl;
test_1(arr,N);
test_2(arr,N);
test_3(arr,N);
return 0;
}
三、折线图
1、2、3、4表示数据规模10^n
(一)顺序递增
(二)顺序递减
(三)随机取值
总体来说,数据规模在10^3以下时三种算法差别不大,而数据规模比较大时,归并排序算法更为优越。