排序实验.docx
- 文档编号:28512334
- 上传时间:2023-07-18
- 格式:DOCX
- 页数:18
- 大小:21.19KB
排序实验.docx
《排序实验.docx》由会员分享,可在线阅读,更多相关《排序实验.docx(18页珍藏版)》请在冰豆网上搜索。
排序实验
排序算法综合实验
1、实验目的
通过上机来体验和掌握课本的有关基本知识,加深对排序算法的认识
2、实验要求
1.实现基本排序方法:
直接插入、希尔、直接选择、冒泡、快速、堆、二路归并;
2.每种基本排序方法尽量给出多种实现(包括改进);
3.给出实验结果:
(1)随机生成若干个随机数进行排序(如n=104,2*104,105,…等),记录每个排序的时间耗费、比较次数、移动次数。
(2)分别给出正序和反序的初始序列进行排序,检验算法对初始序列的敏感程度。
(3)给出实验结果、原因分析、结论等。
(4)所有实验结果汇集成一张表。
实验结果
CPU
AMDE2-3000M1.8GHZ
姓名
内存
4.00GB
学号
主板
华硕M3N78SE
班级
操作系统
64位操作系统
电话
编译软件
C-free4.0
10^4
2*10^4
10^5
2*10^5
10^6
2*10^6
10^7
2*10^7
10^8
10^5
正序
逆序
直接插入
(带监视哨)
M
24.884
100.178
2500.4
9995.8
0
5000.15
C
24.874
100.158
2500.3
9995.6
0.099999
5000.05
t(时间)
0.616
2.678
64.105
282.909
>5min
0.002
174.436
直接插入
(无监视哨)
M
24.884
100.178
2500.4
9995.8
0
5000.15
C
24.874
100.158
2500.3
9995.6
0.099999
4999.95
t
0.517
2.676
54.777
61.506
>5min
0.002
126.462
二分插入
M
24.884
100.178
2500.4
9995.8
0
5000.15
C
0.128934
0.277904
1.62265
3.44539
0.099999
1.56895
t
0.47
1.952
49.832
261.964
>5min
0.002
107.079
希尔排序
M
0.262822
0.603325
4.38309
0
2.46706
C
0.261664
0.598651
4.29106
1.50001
2.24458
t
0.885
3.468
106.105
>5min
103.001
111.559
直接选择
M
0.02997
0.059961
0.299967
0
0.15
C
49.995
199.99
4999.95
4999.95
4999.95
t
0.936
3.713
113.461
>5min
111.986
126.952
冒泡(上升)
M
74.592
300.414
7500.6
29986.2
0
14999.9
C
49.9905
199.985
4999.94
19999.9
0.099999
4999.95
t
1.759
7.023
177.505
704.962
>5min
0.002
216.299
冒泡(下沉)
M
74.592
300.414
7500.6
0
14999.9
C
49.9904
199.96
4999.78
0.099999
4999.95
t
1.776
7.049
177.048
>5min
0.002
216.297
双向冒泡
M
74.592
300.414
7500.6
0
14999.9
C
37.3219
151.089
3751.37
0.099999
4999.95
t
1.342
5.464
143.011
>5min
0.002
247.038
快速
M
0.218131
0.466222
2.67048
5.61375
31.5496
66.0204
363.81
757.839
4134.94
C
0.353081
0.756008
4.49691
9.75604
54.1195
117.44
654.205
1344.23
7331.99
t
0.007
0.015
0.091
0.201
1.371
2.458
14.854
30.18
164.437
堆排序
M
0.174323
0.368419
2.07479
4.34955
24.0491
50.0967
273.831
567.665
2.15085
1.99743
C
0.174822
0.379389
2.24634
4.79156
27.4497
57.8984
324.139
678.283
2.32649
2.14524
t
0.01
0.017
0.109
0.25
1.75
3.751
23.946
51.196
>5min
0.104
0.086
二路归并(非递归)
M
0.14
0.32
1.8
3.6
20
44
240
520
2800
1.8
1.8
C
0.123676
0.267361
1.56651
3.33305
18.7166
39.4319
224.022
468.006
2540.15
0.877968
0.815024
t
0.005
0.013
0.068
0.154
0.84
1.853
10.808
22.889
137.508
0.048
0.064
实验程序
#defineCPPC++
#defineMPPM++
#defineMP2M+=2
#defineMP3M+=3
#include
#include
#include
#include
#include
constintmaxsize=10000;//数据表容量
typedefintdatatype;
typedefstruct{
datatypekey;//关键字域
//othertypeother;//其它域
}rectype;//记录类型
typedefrectypelist[maxsize+2];//数据表类型,0号单元不用
__int64C,M;//比较和移动次数
voidcheck(listR,intn){//检验排序结果
inti;
for(i=2;i<=n;i++)
if(R[i].key \n";return;} cout<<"Correct! "; } voiddisp(listR,intn){//显示排序后的结果 inti; for(i=1;i<=n;i++){ cout< //if(i%20==0)cout< } cout< } voidInsertSort1(listR,intn){//直接插入排序,带监视哨(并不改变关键字次数) inti,j; for(i=2;i<=n;i++){//依次插入R[2],R[3],…,R[n] if(CPP,R[i].key>=R[i-1].key)continue; //R[i]大于有序区最后一个记录,则本趟不需插入 MPP,R[0]=R[i];//R[0]是监视哨 j=i-1; do{//查找R[i]的插入位置 MPP,R[j+1]=R[j];j--;//记录后移,继续向前搜索 }while(CPP,R[0].key MPP,R[j+1]=R[0];//插入R[i] } } voidInsertSort2(listR,intn){//直接插入排序,无监视哨 inti,j;rectypex;//x为辅助量(用R[0]代替时间变长) for(i=2;i<=n;i++){//进行n-1次插入 if(CPP,R[i].key>=R[i-1].key)continue; MPP,x=R[i];//待排记录暂存到x j=i-1; do{//顺序比较和移动 MPP,R[j+1]=R[j];j--; }while(j>=1&&(CPP,x.key MPP,R[j+1]=x;//插入R[i] } } voidInsertSort3(listR,intn){//改进: 在查找插入位置时采用二分查找,即二分插入排序 inti,j,low,high,mid; for(i=2;i<=n;i++){//依次插入R[2],R[3],...,R[n] if(CPP,R[i].key>=R[i-1].key)continue;//R[i]大于有序区最后一个记录,不需插入 MPP,R[0]=R[i]; low=1;high=i-1; while(low<=high){//查找R[i]的插入位置 mid=(low+high)/2; if(CPP,R[0].key elselow=mid+1; } for(j=i-1;j>=high+1;j--) MPP,R[j+1]=R[j];//记录后移 MPP,R[high+1]=R[0]; } } voidShellSort(listR,intn){//希尔排序 inth,i,j,k; for(h=n/2;h>=1;h=h/2){ for(i=1;i<=h;i++){//i为组号 for(j=i+h;j<=n;j+=h){//每组从第2个记录开始插入 if(CPP,R[j].key>=R[j-h].key)continue;//R[j]大于有序区最后一个记录,则不需要插入 MPP,R[0]=R[j];//R[0]保存待插入记录,但不是监视哨 k=j-h;//待插记录的前一个记录 do{//查找正确的插入位置 MPP,R[k+h]=R[k];k=k-h;//后移记录,继续向前搜索 }while(k>0&&(CPP,R[0].key MPP,R[k+h]=R[0];//插入R[j] } } if(h==1)break; } } voidSelectSort(listR,intn){ inti,j,k; for(i=1;i<=n-1;i++){//n-1趟排序 k=i; for(j=i+1;j<=n;j++)//在当前无序区中找最小的记录R[k] if(R[j].key<=R[k].key)CPP,k=j; if(k! =i){MP3,R[0]=R[i];R[i]=R[k];R[k]=R[0];}//交换R[i]和R[k],R[0]作辅助 } } voidBubbleSort1(listR,intn){//上升法冒泡排序 inti,j,flag;rectypex;//x为辅助量(可用R[0]代替) for(i=1;i<=n-1;i++){//做n-1趟扫描 flag=0;//置未交换标志 for(j=n;j>=i+1;j--)//从下向上扫描 if(CPP,R[j].key flag=1; MP3,x=R[j];R[j]=R[j-1];R[j-1]=x;//交换 } if(! flag)break;//本趟未交换过记录,排序结束 } } voidBubbleSort2(listR,intn){//下沉法,冒泡排序 inti,j,flag;rectypex;//x为辅助量(可用R[0]代替) for(i=1;i<=n-1;i++){//做n-1趟扫描 flag=0;//置未交换标志 for(j=1;j<=n-i;j++)//从上向下扫描 if(CPP,R[j].key>R[j+1].key){//交换记录 flag=1; MP3,x=R[j];R[j]=R[j+1];R[j+1]=x;//交换 } if(! flag)break;//本趟未交换过记录,排序结束 } } voidBubbleSort3(listR,intn){//双向冒泡排序 inti,j,k,flag;rectypex;//改进: 双向冒泡排序,每趟排序同时使轻气泡向上"漂浮",重气泡向下"漂浮" i=1;j=n; while(i flag=0;//置未交换标志 for(k=j;k>=i+1;k--)//从下向上扫描 if(CPP,R[k].key flag=1; MP3,x=R[k];R[k]=R[k-1];R[k-1]=x;//交换 } if(! flag)break;//本趟未交换过记录,排序结束 i++; flag=0; for(k=i;k<=j-1;k++)//从上向下扫描 if(CPP,R[k].key>R[k+1].key){//交换记录 flag=1; MP3,x=R[k];R[k]=R[k+1];R[k+1]=x; } if(! flag)break; j--; } } intPartition(listR,intp,intq){//对R[p]到R[q]划分,返回基准位置 inti,j;rectypex;//辅助量(可用R[0]代替) i=p;j=q;MPP,x=R[p];//x存基准(无序区第一个记录) do{ while((CPP,R[j].key>=x.key)&&i if(i while((CPP,R[i].key<=x.key)&&i if(i }while(i MPP,R[i]=x;//基准移到最终位置 returni;//最后i=j } voidQuickSort1(listR,ints,intt){//对R[s]到R[t]快速排序,递归算法 inti; if(s>=t)return;//只有一个记录或无记录时无需排序 i=Partition(R,s,t);//对R[s]到R[t]做划分 QuickSort1(R,s,i-1);//递归处理左区间 QuickSort1(R,i+1,t);//递归处理右区间 } voidSift(listR,intp,intq)//堆范围为R[p]~R[q],调整R[p]为堆,非递归算法 {inti,j; MPP,R[0]=R[p];//R[0]作辅助量 i=p; j=2*i; while(j<=q) { if(j if(CPP,R[0].key>=R[j].key)break;//跟结点键值大于孩子结点,已经是堆,调整结束 MPP,R[i]=R[j];//将R[j]换到双亲位置上 i=j;//修改当前被调整结点 j=2*i;//j指向R[p]的左孩子 } MPP,R[i]=R[0]; } voidHeapSort(listR,intn){//对R[1]~R[n]进行堆排序 inti; for(i=n/2;i>=1;i--) Sift(R,i,n); for(i=n;i>=2;i--){//进行n-1趟堆排序 R[0]=R[1];R[1]=R[i];R[i]=R[0];//堆顶和当前堆底交换,R[0]作辅助量 Sift(R,1,i-1); } } voidMerge(listR,listR1,intlow,intmid,inthigh){ //合并R的两个子表: R[low]~R[mid]、R[mid+1]~R[high],结果在R1中 inti,j,k; i=low; j=mid+1; k=low; while(i<=mid&&j<=high) if(CPP,R[i].key<=R[j].key)MPP,R1[k++]=R[i++];//取小者复制 elseMPP,R1[k++]=R[j++]; while(i<=mid)MPP,R1[k++]=R[i++];//复制左子表的剩余记录 while(j<=high)MPP,R1[k++]=R[j++];//复制右子表的剩余记录 } voidMergePass(listR,listR1,intn,intlen){//对R做一趟归并,结果在R1中 inti,j; i=1;//i指向第一对子表的起始点 while(i+2*len-1<=n){//归并长度为len的两个子表 Merge(R,R1,i,i+len-1,i+2*len-1); i=i+2*len;//i指向下一对子表起始点 } if(i+len-1 Merge(R,R1,i,i+len-1,n); else//子表个数为奇数,剩一段 for(j=i;j<=n;j++)//将最后一个子表复制到R1中 MPP,R1[j]=R[j]; } voidMergeSort(listR,listR1,intn){//对R二路归并排序,结果在R中(非递归算法) intlen; len=1; while(len MergePass(R,R1,n,len);len=len*2;//一趟归并,结果在R1中 MergePass(R1,R,n,len);len=len*2;//再次归并,结果在R中 } } intrandom1(intnum){returnrand();}//0~RAND_MAX=32767 intrandom3(intnum){//素数模乘同余法,0~M intA=16807;//16807,39722040,764261123,63036001648271? intM=2147483647;//有符号4字节最大素数,2^31-1 intQ=M/A; intR=M%A; staticintx=1,n=0,g=0;//seed(setto1) staticdoubler,r1=0,r2=0; intx1; x1=A*(x%Q)-R*(x/Q); if(x1>=0)x=x1; elsex=x1+M; returnx; } intmain(){ rectype*R,*R1,*S;//R1用于归并排序的辅助存储,S用于保存初始排序数据 R=newlist;if(R==NULL){cout<<"数组太大! \n";exit(-1);} R1=newlist;if(R1==NULL){cout<<"数组太大! \n";exit(-1);} S=newlist;if(S==NULL){cout<<"数组太大! \n";exit(-1);} inti,n=maxsize; intchoice; clock_tt1,t2; floats,t; //srand((unsigned)time(NULL)); for(i=1;i<=n;i++) S[i].key=random3(n);//生成0-n之间的随机数 do{ C=M=0; cout<<"请输入a,b,或者c(a代表正序,b代表逆序,c代表无序)"< charch; cin>>ch; switch(ch){ case'c': { for(i=1;i<=n;i++) R[i].key=S[i].key;cout<<"您的原始数据为无序,请选择以下排序方式"< break;}//取出初始数据用于排序 case'a': {for(i=1;i<=n;i++) R[i].key=i;cout<<"您的原始数据为正序,请选择以下排序方式"< case'b': {for(i=1;i<=n;i++) R[i].key=n-i+1;cout<<"您的原始数据为逆序,请选择以下排序方式"< default: cout<<"error"< cout<<"选择排序方法(0: 退出): \n\ 10: 直接插入(带监视哨)15: 直接插入(无监视哨)\n\ 20: 二分插入排序\n\ 25: 希尔排序30: 直接选择排序\n\ 35: 冒泡(上升)40: 冒泡(下沉)\n\ 45: 双向冒泡排序50: 快速(递归)\n\ 55: 堆排序60: 二路归并(非递归)\n\"; cin>>choice; switch(choice){ case10: t1=clo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 排序 实验
![提示](https://static.bdocx.com/images/bang_tan.gif)