实验内容
(1)针对插入排序、归并排序和快速排序算法,编写完整程序实现三种排序算法。
(2)采用随机生成测试用例的方法生成三组算法测试数据集。三组测试数据集的规模分别是:20000个数据、50000个数据、200000个数据。
(3)采用具有计时功能的函数,记录三种排序算法在三个数据集中进行排序所使用的时间,横向比较三种排序算法的性能。
(4)结合三种算法的逻辑过程、实践过程和实验结果,对三种算法的时间复杂度和空间复杂度进行分析。:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#define N 200000
//插入排序, 对R[0..n-1]按递增有序进行直接插入排序
void InsertSort(int R[],int n) //数组R[]用于存放待排序数组,n代表需排序数组数目
{ int i, j; int tmp; //以下tmp代表从无序区插入到有序区的数字
for (i=1;i<n;i++) //从第一个数字开始,设第一个数字即R[1]为有序区,R[2,···,n]为无序区 ,再使用增量法每次使有序区增加一个元素
{
if (R[i]<R[i-1]) //当反序时
{ tmp=R[i]; //将R[i]的值赋给tmp
j=i-1;
do //找R[i]的插入位置
{ R[j+1]=R[j]; //将关键字大于R[i]的记录后移(因为R[j]大于R[i],所以将R[j]向后移动
j--; //再次将R[j]设为当前数的前一个数
} while (j>=0 && R[j]>tmp);
R[j+1]=tmp; //在j+1处插入R[i]
}
}
}
//快速排序
int partition(int R[],int s,int t) //一趟划分
{
int i=s,j=t;
int tmp=R[i]; //以R[i]为基准
while (i<j) //从两端交替向中间扫描,直至i=j为止
{ while (j>i && R[j]>=tmp)
j--; //从右向左扫描,找一个小于tmp 的R[j]
R[i]=R[j]; //找到这样的R[j],放入R[i]处
while (i<j && R[i]<=tmp)
i++; //从左向右扫描,找一个大于tmp的R[i]
R[j]=R[i]; //找到这样的R[i],放入R[j]处
}
R[i]=tmp;
return i;
}
void QuickSort(int R[],int s,int t) //对R[s..t]的元素进行递增快速排序
{
int i;
if (s<t) //区间内至少存在两个元素的情况
{ i=partition(R,s,t);
QuickSort(R,s,i-1); //对左区间递归排序
QuickSort(R,i+1,t); //对右区间递归排序
}
}
//归并排序
void Merge(int R[],int low,int mid,int high) //一次归并:将两个有序表R[low..mid]和R[mid+1..high]归并为一个有序表R[low..high]中
{
int *R1;
int i=low,j=mid+1,k=0; //k是R1的下标,i、j分别为第1、2段的下标
R1=(int *)malloc((high-low+1)*sizeof(int)); //动态分配空间
while (i<=mid && j<=high) //在第1段和第2段均未扫描完时循环
if (R[i]<=R[j]) //将第1段中的记录放入R1中
{
R1[k]=R[i];
i++;k++;
}
else //将第2段中的记录放入R1中
{
R1[k]=R[j];
j++;k++;
}
while (i<=mid) //将第1段余下部分复制到R1
{
R1[k]=R[i];
i++;k++;
}
while (j<=high) //将第2段余下部分复制到R1
{
R1[k]=R[j];
j++;k++;
}
for (k=0,i=low;i<=high;k++,i++) //将R1复制回R中
R[i]=R1[k];
}
void MergeSortDC(int R[],int low,int high)
{
//用分治法对R[low..high]进行二路归并排序
int mid;
if(low<high)
{ //区间长度大于1
mid=(low+high)/2; //分解
MergeSortDC(R,low,mid); //递归地对R[low..mid]排序
MergeSortDC(R,mid+1,high); //递归地对R[mid+1..high]排序
Merge(R,low,mid,high); //组合,将两个有序区归并为一个有序区
}
}
int main()
{
int R[N]; //用R[N]来存放生成的随机数
int time_start, time_end; //分别记录排序开始前的时间和排序后的时间
for(int i = 0; i < N; i ++) //生成随机数并将这些随机数存在数组中
R[i] = rand();
time_start = clock();
InsertSort(R,N);
time_end = clock();
printf("插入排序用时:%d 毫秒\n", time_end-time_start);
for(int i = 0; i < N; i ++)
R[i] = rand();
time_start = clock();
QuickSort(R,0,N-1);
time_end = clock();
printf("快速排序用时:%d 毫秒\n", time_end-time_start);
for(int i = 0; i < N; i ++)
R[i] = rand();
time_start = clock();
MergeSortDC(R,0,N-1);
time_end = clock();
printf("归并排序用时:%d 毫秒\n", time_end-time_start);
}