北邮数据结构实验报告实验四排序含源码.docx
《北邮数据结构实验报告实验四排序含源码.docx》由会员分享,可在线阅读,更多相关《北邮数据结构实验报告实验四排序含源码.docx(18页珍藏版)》请在冰豆网上搜索。
![北邮数据结构实验报告实验四排序含源码.docx](https://file1.bdocx.com/fileroot1/2022-11/23/14cc34d2-fb2b-41ec-aed6-3fd47496c735/14cc34d2-fb2b-41ec-aed6-3fd47496c7351.gif)
北邮数据结构实验报告实验四排序含源码
数据结构实验报告
实验名称:
实验4——排序
*******
班级:
2012211103
班内序号:
03
学号:
*********4
日期:
2013年12月18日
1.实验要求
使用简单数组实现下面各种排序算法,并进行比较。
排序算法:
1、插入排序
2、希尔排序
3、冒泡排序
4、快速排序
5、简单选择排序
6、堆排序(选作)
7、归并排序(选作)
8、基数排序(选作)
9、其他
要求:
1、测试数据分成三类:
正序、逆序、随机数据
2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)
4、对2和3的结果进行分析,验证上述各种算法的时间复杂度
编写测试main()函数测试线性表的正确性。
2.程序分析
(1)、设计一个菜单,格式如下:
1、直接插入排序2、希尔排序3、冒泡排序4、快速排序
5、选择排序6、堆排序7、退出
(2)、选择不同的菜单但进行相应的排序,并给出排序的关键字序列。
2.1存储结构
2.2关键算法分析
本程序包含了9个函数,它们分别是:
(1)、直接插入排序的算法函数InsertSort()。
voidInsertSort(SqList&L)
{
inti,j;
for(i=2;i<=L.length;i++)
{
if(L.r[i].key{
L.r[0]=L.r[i];
L.r[i]=L.r[i-1];
for(j=i-2;(L.r[0].keyL.r[j+1]=L.r[0];
}
}
}
(2)、希尔排序的算法函数ShellSort()。
voidShellSort(SqList&L)
{
inti,j;
intdk=1;//增量
while(dk<=L.length/3)
dk=3*dk+1;//增大增量
while(dk>0)
{
dk/=3;//减小增量
for(i=dk;i<=L.length;i++){
L.r[0].key=L.r[i].key;
j=i;
while((j>=dk)&&(L.r[j-dk].key>L.r[0].key)){
L.r[j].key=L.r[j-dk].key;
j-=dk;
}
L.r[j].key=L.r[0].key;
}
}
}
(3)、冒泡排序算法函数BubbleSort()。
voidBubbleSort(SqList&L)
{
inti,j;
for(i=0;i{
intflag=1;
for(j=0;jif(L.r[j].key>L.r[j+1].key)
{
flag=0;
inttemp;
temp=L.r[j].key;
L.r[j].key=L.r[j+1].key;
L.r[j+1].key=temp;
}
//若无交换说明已经有序
if(flag==1)
break;
}}
(4)、快速排序的算法函数Partition()。
voidBubbleSort(SqList&L)
{
inti,j;
for(i=0;i{
intflag=1;
for(j=0;jif(L.r[j].key>L.r[j+1].key)
{
flag=0;
inttemp;
temp=L.r[j].key;
L.r[j].key=L.r[j+1].key;
L.r[j+1].key=temp;
}
//若无交换说明已经有序
if(flag==1)
break;
}}
(5)、选择排序算法函数SelectSort()。
voidSelectSort(SqList&L)
{
intmin;
intj;
for(inti=0;i{//选择第i小的记录,并交换
j=i;
min=L.r[i].key;
for(intk=i;k{//在R[i..n-1]中选择最小的记录
if(L.r[k].key{
min=L.r[k].key;
j=k;
}
}
if(i!
=j)
{//与第i个记录交换
inttemp=L.r[i].key;
L.r[i].key=L.r[j].key;
L.r[j].key=temp;
}
}
}
(6)、堆排序算法函数HeapAdjust()。
voidHeapAdjust(HeapType&H,ints,intm)
第6/10页
//堆调整,将记录调整为小顶堆intj;
RedTyperc=H.r[s];//暂时存储根结点
for(j=2*s;j<=m;j*=2)
{
//沿着结点记录较小的向下筛选
if(j++j;
if(rc.key>=H.r[j].key)
break;
H.r[s]=H.r[j];
s=j;
}
H.r[s]=rc;
}
voidHeapSort(HeapType&H)
{
inti;
RedTypetemp;
for(i=H.length;i>0;--i)
HeapAdjust(H,i,H.length);
for(i=H.length;i>1;--i)
{
temp=H.r[1];
H.r[1]=H.r[i];
H.r[i]=temp;
HeapAdjust(H,1,i-1);
}
(7)、对存储数字的遍历函数Visit()、初始化函数InitSqList()。
voidVisit(SqListL)
{
for(inti=1;i<=L.length;i++)
cout<cout<}
voidInitSqList(SqList&L,inta[])
{
for(inti=1;i<=L.length;i++)
L.r[i].key=a[i];
}
(8)、主函数main()。
关键算法的时间、空间复杂度:
排序法 平均时间 最差情形 稳定度 额外空间 备注
冒泡 O(n2) O(n2) 稳定 O
(1) n小时较好
交换 O(n2) O(n2) 不稳定 O
(1) n小时较好
选择 O(n2) O(n2) 不稳定 O
(1) n小时较好
插入 O(n2) O(n2) 稳定 O
(1) 大部分已排序时较好
Shell O(nlogn) O(ns)1
(1) s是所选分组
快速 O(nlogn) O(n2) 不稳定 O(nlogn) n大时较好
归并 O(nlogn) O(nlogn) 稳定 O
(1) n大时较好
堆 O(nlogn) O(nlogn) 不稳定 O
(1) n大时较好
2.3其他
3.程序运行结果
主函数流程:
4.总结
首先,对程序的设计缺少优化,本次程序需要运行之后手动进行输入数据,以后可以尝试把数据改为在源代码中输入,这样就可以运行之后马上显示数据,这样就避免了相同数据的重复输入。
此外,生成数组函数及本程序中的代码有的采用了递归形式,如果考虑用栈来模拟的话,效率会有提升,所以运行时间还和代码的实现有关。
本程序出现过的问题是主函数对个函数的调用以及对存储数组的调用上出现了问题,导致排序的结果以及排序的界面出现了问题,得不到实现。
后来对算法进行改进,最终把问题得以解决。
而且以后可以试着去写一段可以计算出时间的函数。
代码
#include
#include
#include
usingnamespacestd;
inti,j,temp,k;//设置全局变量
longdoubleGetNowTime()//取系统时间
{
LARGE_INTEGERlitmp;
LONG64QPart;
QueryPerformanceCounter(&litmp);
QPart=litmp.QuadPart;
return(longdouble)QPart;
}
//插入排序
voidInsertSort(intr[],intn)
{intmove=0,compare=0;
longdoublestart=0,end=0,time=0;
start=GetNowTime();
for(i=2;i{
if(r[i]{compare++;
r[0]=r[i];//设置哨兵,存放待排序记录值
for(j=i-1;r[0]r[j+1]=r[j];//比r[0]大的往后移
r[j+1]=r[0];//插入指定记录值
move=move+3;//关键码的交换按3次记
compare++;
}
}
end=GetNowTime();
time=end-start;
for(k=1;kcout<cout<cout<<"排序所需时间:
"<