一.实验内容:
1、 编写函数分别实现插入排序和归并排序算法
2、 编写主函数通过调用函数实现对待排数据的调用
3、 待排数据利用随机函数循环产生10万个以上的数据
4、 利用求系统时间的函数,分别求出2个排序函数调用前和调用后的时间,计算出插入排序运行时间和归并排序的运行时间
5、 算法的比较:
(1) 相同待排序数据下,插入排序和归并排序算法的运行时间比较;
(2) 同一种排序算法下最好的情况,一般情况,最坏的情况运行时间比较
插入排序:插入即表示将一个新的数据插入到一个有序数组中,并继续保持有序。例如有一个长度为N的无序数组,进行N-1次的插入即能完成排序;第一次,数组第1个数认为是有序的数组,将数组第二个元素插入仅有1个有序的数组中;第二次,数组前两个元素组成有序的数组,将数组第三个元素插入由两个元素构成的有序数组中......第N-1次,数组前N-1个元素组成有序的数组,将数组的第N个元素插入由N-1个元素构成的有序数组中,则完成了整个插入排序。
以下面5个无序的数据为例:
65 27 59 64 58 (文中仅细化了第四次插入过程)
第1次插入: 27 65 59 6458
第2次插入: 27 59 65 6458
第3次插入: 27 59 64 6558
第4次插入: 27 58 59 6465
二.算法分析
三.实验代码
#include<stdio.h>
#include<stdlib.h>//数学
#include<time.h>//时间
void insertSort(long int *, long int); //定义插入排序函数
void merge(long int X[], long int Z[], long int s, long int u, long int v);
void mergePass(long int X[], long int Y[],long int n, long int t);
void mergeSort(long int X[],long int n);
void insertSort(long int *array,long int len)
{
long int i,j,temp;
for(i=1;i<len;i++) //从第二个元素开始
{
temp=array[i]; //取出代插元素
for(j=i-1;j>=0;j--) //带插元素依次和前一个比较,将较大数依次后移
{
if(array[j]>temp)
{
array[j+1]=array[j];
}else
{
break;
}
}
array[j+1] = temp;
}
}
//将有序的X[s..u]和X[u+1..v]归并为有序的Z[s..v]
void merge(long int X[],long int Z[], long int s, long int u, long int v)
{
long int i, j, q;
i = s;
j = u + 1;
q = s;
while( i <= u && j<= v )
{
if( X[i] <= X[j] )
Z[q++] = X[i++];
else
Z[q++] = X[j++];
}
while( i <= u ) //将X中剩余元素X[i..u]复制到Z
Z[q++] = X[i++];
while( j <= v ) //将X中剩余元素X[j..v]复制到Z
Z[q++] = X[j++];
}
/* X[0..n-1]表示参加排序的初始序列
* t为某一趟归并时子序列的长度
* 整型变量i指出当前归并的两个子序列中第1个子序列的第1个元素的位置
* Y[0..n-1]表示这一趟归并后的结果
*/
void mergePass(long int X[], long int Y[], long int n,long int t)
{
int i = 0, j;
while( n - i >= 2 * t ) //将相邻的两个长度为t的各自有序的子序列合并成一个长度为2t的子序列
{
merge(X, Y, i, i + t - 1, i + 2 * t - 1);
i = i + 2 * t;
}
if( n - i > t ) //若最后剩下的元素个数大于一个子序列的长度t时
merge(X, Y, i, i + t - 1, n - 1);
else //n-i <= t时,相当于只是把X[i..n-1]序列中的数据赋值给Y[i..n-1]
for( j = i ; j < n ; ++j )
Y[j] = X[j];
}
void mergeSort(long int X[],long int n)
{
long int t = 1;
long int *Y = (long int *)malloc(sizeof(long int) * n);
while( t < n )
{
mergePass(X, Y, n, t);
t *= 2;
mergePass(Y, X, n, t);
t *= 2;
}
free(Y);
}
void print_array(long int array[],long int n)
{
long int i;
for( i = 0 ; i < n ; ++i )
printf("%d ", array[i]);
printf("\n");
}
int main()
{
printf("请输入要产生的随机数个数:");
double start, finish;
long int a[100005],b[100005],c[100005],d[100005],n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
a[i]=b[i]=rand()%10000+1; //产生随机数
//printf("%d ",b[i]);
}
start=clock();//取开始时间
insertSort(a, n);
finish = clock();//取结束时间
printf("采用插入排序的时间:");
printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);//以秒为单位显示之
// for(i=0;i<n;i++)
// {
// printf("%d ",a[i]);
//}
start=clock();//取开始时间
mergeSort(b,n);
// print_array(b,n);
finish = clock();//取结束时间
printf("采用归并排序的时间:");
printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);//以秒为单位显示之
/* for(i=0; i<n; i++)
printf("%d ", a[i]);*/
printf("\n");
printf("%d个数插入排序最好结果用时:",n);
start=clock();//取开始时间
for(i=0;i<100000;i++)
{
c[i]=i;
}
insertSort(c,i-1);
finish = clock();//取结束时间
printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);
/
/*
for(i=0;i<100;i++)
{
printf("%d ",c[i]);
}
printf("\n\n\n\n\n");
*/
//
printf("%d个数插入排序最坏结果用时:",n);
start=clock();//取开始时间
for(i=99999;i>=0;i--)
{
d[i]=99999-i;
}
insertSort(d,n);
finish = clock();//取结束时间
printf( "\n%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);
/
/*
for(i=0;i<100;i++)
{
printf("%d ",c[i]);
}
printf("\n\n\n\n\n");
*/
//
printf("%d个数归并排序最好结果用时:",n);
start=clock();//取开始时间
for(i=0;i<n;i++)
{
c[i]=i;
}
mergeSort(c,n);
finish = clock();//取结束时间
printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);
printf("%d个数归并排序最坏结果用时:",n);
start=clock();//取开始时间
for(i=n-1;i>=0;i--)
{
d[i]=99999-i;
}
mergeSort(d,n);
/*for(i=0;i<n;i++)
{
printf("%d ",d[i]);
} */
finish = clock();//取结束时间
printf( "\n%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);
return 0;
}
四.实验结果
五.实验分析
在随机数组中,归并排序明显优于插入排序,且数值越大越明显。有序序列结果不明显,但仍然归并排序优于插入排序。