排序算法分析
- 格式:doc
- 大小:335.50 KB
- 文档页数:15
实 验 报 告
课程名称 计算机软件基础
实验项目 排序算法分析
实验仪器 VS2005
系 别__ 光电信息与通信工程
专 业__ __电子信息工程
班级/学号_ _
学生姓名 __ ___________
实验日期 _______________________
成 绩 _______________________
指导教师 _______________________
实验五、排序算法分析
1、实验目的:
掌握顺序表的常用排序方法,掌握算法性能测算技术。通过实验测算各排序算法的性能并进行分析比较。
2、 实验内容:
1) 分别编写函数实现插入排序、冒泡排序和快速排序算法,算法应具有记录比较次数和移动次数的功能,以及显示每趟排序中间结果的功能。
2) 编制一个应用程序,它将随机产生的n个整数插入到一个顺序表中,然后分别用上述排序算法对这个顺序表进行排序,并显示各种方法的比较次数和移动次数;
3) 取n=10,运行程序,检察排序中间结果及次数统计是否正确。
选做内容:
4) 修改程序,关闭算法输出中间结果的功能,然后分别以n=50、500和5000运行这个程序,对次数的统计结果作出分析和解释。
5) 利用计时函数实现对排序算法的运行时间计时。
6) 分析说明:影响排序时间、比较次数及交换次数的因素有哪些?
3、实验步骤 (1)插入排序:
运行结果:
(2)冒泡排序:
运行结果:
(3)快速排序:
运行结果:
(4)比较次数统计与分析
n=50
n=500
n=5000
通过比较可以看出,快速排序效率最高,而且排序数列越多越能显示其效率,冒泡排序和插入排序移动次数相差不大,但是比较次数相差相当大,所以平均来说,冒泡排序的时间复杂度最高,插入排序时间复杂度居中,快速排序最小。
下面的截图更能说明这一点:
由图中我们可以发现,快速排序所花时间最少,插入排序次之,冒泡排序最慢。
影响排序时间、比较次数和移动次数的主要因素有待排序的数据记录数目、序列的初始状态等等。
4、程序清单
#include
#include
#include
#define M 5000 //M为待排序记录的最大数目
struct record {
int key;
int otheritem;
};
typedef struct record RECORD;
long comp; //比较次数
long move; //移动次数
void printfile(RECORD R[],int n) //输出数列
{
int i;
for (i=0;i
{
if(R[i].key<10)printf(" ");
printf(" %d",R[i].key);
}
printf("\n");
}
void insertsort(RECORD R[],int n) //插入排序 { int i, j;
RECORD temp;
for(i=1;i
temp=R[i];
j=i-1;
comp++;
while(temp.key=0){
R[j+1]=R[j];
move++;
comp++;
j--;
}
R[j+1]=temp;
move+=2;
printfile(R,n); //显示中间排序结果
}
}
void bubblesort(RECORD R[], int n)
//修改算法,加入比较次数和移动次数统计,以及显示中间排序结果
{
int i,j,flag; RECORD temp;
i=1;
flag=1;
while(flag)
{
flag=0;
for(j=0;j
{
comp++; //比较次数统计
if(R[j].key>R[j+1].key)
{
temp=R[j];
R[j]=R[j+1];
R[j+1]=temp;
flag=1;
move++; //移动次数统计
printfile(R,n); //显示中间排序结果
}
}
i++;
} }
int qpass(RECORD R[],int n, int low, int high)
//修改算法,加入比较次数和移动次数统计
{
int i, j, k;
RECORD x;
i=low;
j=high;
x=R[low];
k=x.key;
while(i
while((i=k))
{
j--;
comp++; //比较次数
}
R[i]=R[j];
move++; //移动次数
printfile(R,n); //显示中间排序结果
while((i
{ i++;
comp++; //比较次数
}
R[j]=R[i];
move++; //移动次数
printfile(R,n); //显示中间排序结果
}
R[i]=x;
return(i);
}
void quicksort(RECORD R[], int n, int low, int high)//快速排序
{
int i;
if (low
{
i=qpass(R,n,low,high);
quicksort(R,n,low,i-1); //递归调用
quicksort(R,n,i+1,high); //递归调用
}
}
void main()
{
RECORD file[M],file1[M],file2[M];
int i,n;
clock_t start,end; //记录起始时间和结束时间
double duration; //记录排序时间
printf("输入记录个数: ");
scanf("%d", &n);
//产生待排序文件
srand((unsigned)time(NULL));
for (i=0; i
{
file[i].key=rand()%100;
file1[i]=file[i];
file2[i]=file[i];
}
printf("原始数据: \n");
printfile(file,n);
comp=0; move=0;
printf("插入排队过程:\n"); //printfile(file,n);
start=clock(); //插入排序起始时间
insertsort(file,n);
end=clock(); //插入排序结束时间
duration=(double)(end-start); //插入排序时间
//显示统计结果
printf("比较次数:%d\n" ,comp);
printf("移动次数:%d\n",move);
printf("时间:%.2f\n\n",duration); //输出插入排序时间
comp=0; move=0;
printf("冒泡排队过程:\n");
printfile(file1,n);
start=clock(); //冒泡排序起始时间
bubblesort(file1,n);
end=clock(); //冒泡排序结束时间
duration=(double)(end-start); //冒泡排序时间
//显示统计结果
printf("比较次数:%d\n" ,comp);
printf("移动次数:%d\n",move);
printf("时间:%.2f\n\n",duration);//输出冒泡排序时间
comp=0; move=0;
printf("快速排队过程:\n");
printfile(file2,n);
start=clock(); //快速排序起始时间
quicksort(file2,n,0,n-1);
end=clock(); //快速排序结束时间
duration=(double)(end-start); //快速排序时间
//显示统计结果
printf("比较次数:%d\n" ,comp);
printf("移动次数:%d\n",move);
printf("时间:%.2f\n",duration); //输出快速排序时间
}
5、总结
这次实验,我学会了三种排序方法,了解了它们的区别,也发现了各种排序算法的适用场合:1)当待排序数目较小时,直接插入排序较好;
2)当待排序数据的初始状态基本有序(指正序),则应选用插人排序或冒泡排序;
3)若待排序数目较大,则应选择快速排序。
实验过程中出现过很多错误,主要是对排序算法的思想理解不清,在