数据结构算法排序比较.docx
《数据结构算法排序比较.docx》由会员分享,可在线阅读,更多相关《数据结构算法排序比较.docx(18页珍藏版)》请在冰豆网上搜索。
数据结构算法排序比较
课程设计报告
课程设计题目:
排序算法比较
学号:
201120182020
姓名:
揭审鹏
专业:
软件工程
班级:
1121820
指导教师:
张军
目录
1、需求分析………………………………………………3
2、程序的主要功能………………………………………3
3、程序运行平台…………………………………………3
4、算法及时间复杂度……………………………………3
5、测试用例………………………………………………5
6、程序源代码……………………………………………9
7、感想体会与总结………………………………………17
一、需求分析
利用随机函数产生30000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并统计每一种排序上机所花费的时间。
二、程序的主要功能
1.掌握各种排序的基本思想。
2.掌握各种排序方法的算法实现。
3.掌握各种排序方法的优劣分析及花费的时间的计算。
4.掌握各种排序方法所适应的不同场合。
三、程序运行平台
VisualC++6.0版本
四、算法及时间复杂度
(一)各个排序是算法思想:
(1)直接插入排序:
将一个记录插入到已排好的有序表中,从而得到一个新的,记录数增加1的有序表。
(2)起泡排序:
首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换,然后比较第二个记录和第三个记录的关键字。
依此类推,直到第N-1和第N个记录的关键字进行过比较为止。
上述为第一趟排序,其结果使得关键字的最大纪录被安排到最后一个记录的位置上。
然后进行第二趟起泡排序,对前N-1个记录进行同样操作。
一共要进行N-1趟起泡排序。
(3)快速排序:
通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序。
(4)选择排序:
通过N-I次关键字间的比较,从N-I+1个记录中选出关键字最小的记录,并和第I(1<=I<=N)个记录交换。
(5)堆排序:
在堆排序的算法中先建一个大顶堆,既先选得一个关键字作为最大的记录并与序列中最后一个记录交换,然后对序列中前N-1记录进行选择,重新将它调整成一个大顶堆,如此反复直到排序结束。
(6)归并排序:
按最低位优先法先对低位关键字进行排序,直到对最高位关键字排序为止,经过若干次分配和收集来实现排序
(二)时间复杂度分析
排序算法
最差时间
时间复杂度
是否稳定?
插入排序
O(n2)
O(n2)
稳定
冒泡排序
O(n2)
O(n2)
稳定
快速排序
O(n2)
O(n*log2n)
不稳定
选择排序
O(n2)
O(n2)
稳定
堆排序
O(n*log2n)
O(n*log2n)
不稳定
归并排序
O(n*log2n)
O(n2)
稳定
30000个数据的时间比较:
算法名称
用时
直接插入排序
1
起泡排序
4
快速排序
0
选择排序
1
堆排序
0
归并排序
0
5、测试用例
产生30000个随机数
快速排序
堆排序
归并排序
直接插入排序
起泡排序
选择排序
排序时间
六、程序源代码
#include
#include
#include
#include
constintN=30000;
#defineElemTypeint
//以下为起泡排序
voidBubblesort(ElemTypeR[],intn)
{
intflag=1;//当flag为0,停止排序
for(inti=1;i{
//i表示趟数,最多n-1趟
flag=0;//开始时元素未交换
for(intj=n-1;j>=i;j--)
if(R[j]{
//发生逆序
ElemTypet=R[j];
R[j]=R[j-1];
R[j-1]=t;flag=1;//交换,并标记发生了变换
}
if(flag==0)return;
}
}
//以下为直接排序
voidselectsort(ElemTypeR[],intn)
{
inti,j,m;ElemTypet;
for(i=0;i{
m=i;
for(j=i+1;jif(R[j]if(m!
=i)
{
t=R[i];
R[i]=R[m];
R[m]=t;
}
}
}
//以下为直接插入排序
voidinsertsort(ElemTypeR[],intn)
//待排序元素用一个R表示,数组有n个元素
{
for(inti=1;i{
ElemTypetemp=R[i];//把待排序元素赋给temp
intj=i-1;
while((j>=0)&&(temp{
R[j+1]=R[j];j--;//顺序比较和移动
}
R[j+1]=temp;
}
}
//以下为快速排序
voidquicksort(ElemTypeR[],intleft,intright)
{
inti=left,j=right;
ElemTypetemp=R[i];
while(i{
while((R[j]>temp)&&(j>i))
j=j-1;
if(j>i)
{
R[i]=R[j];
i=i+1;
}
while((R[i]<=temp)&&(j>i))
i=i+1;
if(i{
R[j]=R[i];
j=j-1;
}
}//一次划分得到的基准值的正确位置
R[i]=temp;
if(leftif(i+1}
//以下为堆排序
voidcreatheap(ElemTypeR[],inti,intn)
//建立大根堆
{
intj;ElemTypet;
t=R[i];j=2*i;
while(j{
if((jj++;
if(t{
R[i]=R[j];
i=j;
j=2*i;
}
elsej=n;
R[i]=t;
}
}
voidheapsort(ElemTypeR[],intn)//堆排序
{
ElemTypet;
for(inti=n/2;i>=0;i--)
creatheap(R,i,n);
for(i=n-1;i>=0;i--)
{
t=R[0];
R[0]=R[i];
R[i]=t;
creatheap(R,0,i-1);
}
}
//以下为归并排序
voidmerge(ElemTypeR[],ElemTypeA[],ints,intm,intt)
//对两个子区间R[s]~R[m]和R[M+1]~R[t]进行合并,结果存入A中
{
inti,j,k;
i=s;j=m+1;k=s;
while((i<=m)&&(j<=t))
if(R[i]<=R[j])
{A[k]=R[i];i++;k++;}
else
{A[k]=R[j];j++;k++;}
while(i<=m)
{A[k]=R[i];i++;k++;}
while(j<=t)
{A[k]=R[j];j++;k++;}
}
voidmergepass(ElemTypeR[],ElemTypeA[],intn,intc)
//对R数组做一趟归并,结果存入A数组中,n为元素个数,c为区间长度
{
inti,j;
i=0;
while(i+2*c-1<=n-1)
{
//长度均为c的两个区间合并成一个区间
merge(R,A,i,i+c-1,i+2*c-1);
i+=2*c;
}
if(i+c-1merge(R,A,i,i+c-1,n-1);
else
for(j=i;j<=n-1;j++)//仅剩一个区间时,直接复制到A中
A[j]=R[j];
}
voidmergesort(ElemTypeR[],intn)
{
intc=1;ElemTypeA[N];
while(c{
mergepass(R,A,n,c);//一次合并,结果存入A中
c*=2;
mergepass(R,A,n,c);//再次合并,结果存入A中
c*=2;
}
}
voidprint(ElemTypeR[],intn)
{
for(inti=0;i<=n-1;i++)
{if(i%10==0){cout<cout<}
cout<}
voidmain()
{
charch;
ElemTypeR[N],T[N];
time_tt1,t2;
doublett1,tt2,tt3,tt4,tt5,tt6;
srand(0);
for(inti=0;i<=N-1;i++)
T[i]=rand();//产生随机数
print(T,N);//输出随机数
cout<<"快速排序开始(y/n)";
cin>>ch;
if(ch=='y')
{
for(i=0;it1=time(NULL);
quicksort(R,0,N-1);
t2=time(NULL);
tt1=difftime(t2,t1);
print(R,N);
}
cout<<"堆排序开始(y/n)";
cin>>ch;
if(ch=='y')
{
for(i=0;it1=time(NULL);
heapsort(R,N);
t2=time(NULL);
tt2=difftime(t2,t1);
print(R,N);
}
cout<<"归并排序开始(y/n)";
cin>>ch;
if(ch=='y')
{
for(i=0;it1=time(NULL);
mergesort(R,N);
t2=time(NULL);
tt3=difftime(t2,t1);
print(R,N);
}
cout<<"直接插入排序开始(y/n)";
cin>>ch;
if(ch=='y')
{
for(i=0;it1=time(NULL);
insertsort(R,N);
t2=time(NULL);
tt4=difftime(t2,t1);
print(R,N);
}
cout<<"起泡排序开始(y/n)";
cin>>ch;
if(ch=='y')
{
for(i=0;it1=time(NULL);
Bubblesort(R,N);
t2=time(NULL);
tt5=difftime(t2,t1);
print(R,N);
}
cout<<"选择排序开始(y/n)";
cin>>ch;
if(ch=='y')
{
for(i=0;it1=time(NULL);
selectsort(R,N);
t2=time(NULL);
tt6=difftime(t2,t1);
print(R,N);
}
cout<<"快速排序的时间为:
"<cout<<"堆排序的时间为:
"<cout<<"归并排序的时间为:
"<cout<<"直接插入排序的时间为:
"<cout<<"起泡排序的时间为:
"<cout<<"选择排序的时间为:
"<
}
七感想体会与总结
1、做什么都需要耐心,做设计写程序更需要耐心。
一开始的时候,我写函数写的很快,可是等最后调试的时候发现错误很隐蔽,就很费时间了。
后来我先在纸上构思出函数的功能和参数,考虑好接口之后才动手编,这样就比较容易成功了。
2、做任何事情我决定都应该有个总体规划。
之后的工作按照规划逐步展开完成。
对于一个完整的程序设计,首先需要总体规划写程序的步骤,分块写分函数写,然后写完一部分马上纠错调试。
而不是像我第一个程序,一口气写完,然后再花几倍的时间调试。
一步步来,走好一步再走下一步。
写程序是这样,做项目是这样,过我们的生活更是应该这样。
3、感觉一开始设计结构写函数体现的是数据结构的思想,后面的调试则更加体现了人的综合素质,专业知识、坚定耐心、锲而不舍,真的缺一不可啊。
4、通过这次课设,不仅仅复习了C++语言相关知识、巩固了数据结构关于栈和排序的算法等知识,更磨练了我的意志。