北邮数据结构实验报告实验四排序含源码.docx

上传人:b****3 文档编号:3490466 上传时间:2022-11-23 格式:DOCX 页数:18 大小:89.49KB
下载 相关 举报
北邮数据结构实验报告实验四排序含源码.docx_第1页
第1页 / 共18页
北邮数据结构实验报告实验四排序含源码.docx_第2页
第2页 / 共18页
北邮数据结构实验报告实验四排序含源码.docx_第3页
第3页 / 共18页
北邮数据结构实验报告实验四排序含源码.docx_第4页
第4页 / 共18页
北邮数据结构实验报告实验四排序含源码.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

北邮数据结构实验报告实验四排序含源码.docx

《北邮数据结构实验报告实验四排序含源码.docx》由会员分享,可在线阅读,更多相关《北邮数据结构实验报告实验四排序含源码.docx(18页珍藏版)》请在冰豆网上搜索。

北邮数据结构实验报告实验四排序含源码.docx

北邮数据结构实验报告实验四排序含源码

数据结构实验报告

实验名称:

实验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].key

L.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;j

if(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;j

if(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;k

cout<

cout<

cout<<"排序所需时间:

"<

"<

"<

cout<

}

//希尔排序

voidShellSort(intr[],intn)

{

intmove=0,compare=0;

longdoublestart=0,end=0,time=0;

start=start=GetNowTime();

intd;//定义增量

for(d=n/2;d>=1;d=d/2)//以增量为d进行直接插入排序

{

for(i=d+1;i

{

compare++;

r[0]=r[i];//设置哨兵,暂存被插入记录

for(j=i-d;j>0&&r[0]

r[j+d]=r[j];//记录后移d个位置

r[j+d]=r[0];//插入指定记录值

move=move+3;

compare++;

}

}

end=GetNowTime();

time=end-start;

for(i=1;i

cout<

cout<

cout<<"排序所需时间:

"<

"<

"<

cout<

}

//改进型起泡排序

voidBubbleSort(intr[],intn)

{

longdoublestart=0,end=0,time=0;

intmove=0,compare=0;

intexchange;

intbound;

exchange=n-1;//第一趟起泡排序的范围是r[0]到r[n-1]

start=GetNowTime();

while(exchange)//仅当上一趟排序有记录交换才进行本趟排序

{

bound=exchange;//表示无序的范围

exchange=0;

for(intj=0;j

if(r[j]>r[j+1])

{

temp=r[j];//交换r[i]和r[i+1]

r[j]=r[j+1];

r[j+1]=temp;

move=move+3;

exchange=j;//记录每一次发生记录交换的位置,即记录无序区的位置

}

compare++;

}

end=GetNowTime();

time=end-start;

for(inti=0;i

cout<

cout<

cout<<"排序所需时间:

"<

"<

"<

cout<

}

//快速排序一次划分

intEmove=0,Ecompare=0;

longdoubleEtime;

intPartition(intr[],intfirst,intend)

{

i=first;//初始化

j=end;

while(i

{

while(i

{Ecompare++;j--;}//右侧扫描

Ecompare++;

if(i

{

temp=r[i];//将较小记录交换到前面

r[i]=r[j];

r[j]=temp;

Emove=Emove+3;

/*i++;*/

}

while(i

{Ecompare++;i++;}//左侧扫描,小于轴值的不移动,找到大于轴值的

Ecompare++;

if(i

{

temp=r[j];

r[j]=r[i];

r[i]=temp;//将较大记录交换到后面

Emove=Emove+3;

/*j--;*/

}

}

 

returni;//i为轴值记录的最终位置

}

//快速排序,在一次排序结束后,左边区的元素都比右边区的小,只要分开再排序即可

voidQuickSort(intr[],intfirst,intend2)

{

longdoublestart=0,end=0;

start=GetNowTime();

if(first

{//递归结束

intpivot=Partition(r,first,end2);//一次划分

QuickSort(r,first,pivot-1);//递归地对左侧子序列进行快速排序

QuickSort(r,pivot+1,end2);//递归地对右侧子序列进行快速排序

}

end=GetNowTime();

Etime=end-start;

}

voidPrint()

{

cout<

"<

"<

"<

}

//简单选择排序,每一趟都找到最小值与比较域内第一个值交换

voidSelectSort(intr[],intn)

{

longdoublestart=0,end=0,time=0;

intcompare=0,move=0;

intindex;//设置关键值下标

start=GetNowTime();

for(i=0;i

{

index=i;

for(j=i+1;j

if(r[j]

index=j;//更新关键值记录

if(index!

=i)//若第一个是最小值就不用交换

{

temp=r[i];

r[i]=r[index];

r[index]=temp;//交换r[i]和关键值记录

move=move+3;

}

compare++;

}

end=GetNowTime();

time=end-start;

for(i=0;i

cout<

cout<

"<

"<

"<

cout<

}

//对数列进行排序

voidpx(intr[],intnumv)

{

cout<<"\n直接顺序排序结果为:

";

InsertSort(r,numv);

cout<<"希尔排序结果为:

";

ShellSort(r,numv);

cout<<"起泡排序结果为:

";

BubbleSort(r,numv-1);

cout<<"快速排序结果为:

";

QuickSort(r,0,numv-1);

for(inti=0;i

cout<

Print();

Emove=0;Ecompare=0;

cout<<"\n";

cout<<"简单选择排序结果为:

";

SelectSort(r,numv-1);

}

//主函数

intmain()

{

constintnumv=11;

inta[numv]={0};

intb[numv]={0};

intc[numv]={0};//初始化

cout<<"请输入10位正整数."<

cout<<"第一组,正序输入a[]=";

try

{

for(i=1;i

cin>>a[i];//从键盘输入待排序记录值

}

catch(char*wrong)

{

cout<

}

px(a,numv);//调用排序函数

cout<<"\n第二组,反序输入b[]=";

try

{

for(i=1;i

cin>>b[i];//从键盘输入待排序记录值

}

catch(char*wrong)

{

cout<

}

px(b,numv);//调用排序函数

cout<<"\n第三组,随机输入c[]=";

try

{

for(i=1;i

cin>>c[i];//从键盘输入待排序记录值

}

catch(char*wrong)

{

cout<

}

px(c,numv);//调用排序函数

return0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1