课程设计内部排序算法比较Word文档格式.docx
《课程设计内部排序算法比较Word文档格式.docx》由会员分享,可在线阅读,更多相关《课程设计内部排序算法比较Word文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
QuickSort(&
进行快速排序,返回关键字比较次数c和移动次数s。
ShellSort(&
进行希尔排序,返回关键字比较次数c和移动次数s。
HeapSort(&
进行堆排序,返回关键字比较次数c和移动次数s。
ListTraveres(visit())
依次对L中的每个元素调用函数visit()。
}ADTOrderableList
2.2本程序包含两个模块:
2.2.1主程序模块:
voidmain(){
初始化;
do{
接受命令;
处理命令;
}while("
命令"
!
="
退出"
);
}
2.2.2可排序表单元模块:
——实现可排序表的抽象数据类型;
主程序模块
↓↓
可排序表单元模块
详细设计
3.1直接插入排序
直接插入排序是一种最简单的排序方法,它的基本操作是将一个记录插入到已牌号序的有序表中,从而得到一个新的、记录数增1的有序表。
其算法如下:
voidinsertsort(sqlistb,intn)
{
inti,j;
ints=0,t=0;
for(i=2;
i<
n;
i++)
b[0]=b[i];
s++;
j=i-1;
t++;
while(b[0].key<
b[j].key)
{
b[j+1]=b[j];
j--;
}
b[j+1]=b[0];
cout<
<
"
移动次数="
s<
"
比较次数="
t<
endl;
3.2折半排序
由于插入排序的基本操作是在一个有序表中进行查找和插入,可知这个“查找”操作可利用“折半查找”来实现,由此进行的插入排序称之为折半插入排序,其算法如下:
voidBInsertSort(int*data,long*p_movetime,long*p_comparetime){
inti,j,amount,low,high,m;
*p_movetime=*p_comparetime=0;
amount=*data;
for(i=2;
i<
=amount;
++i){
*(data)=*(data+i);
(*p_movetime)++;
low=1;
high=i-1;
while(low<
=high){
(*p_comparetime)++;
m=(low+high)/2;
//针对于接下来的*(data)和*(data+m)的比较
if(*(data)<
*(data+m))high=m-1;
elselow=m+1;
}
for(j=i-1;
j>
=high+1;
--j){
*(data+j+1)=*(data+j);
*(data+high+1)=*(data);
(*p_movetime)++;
3.3二路插入排序
二路插入排序是在折半插入排序的基础上再改进之,其目的是减少排序过程中移动记录的次数,但为此需要n个记录的辅助空间。
算法如下:
voidTwoWaySort(int*data,long*p_movetime,long*p_comparetime){
intamount;
intfirst,final,i,j;
//first和final分别指示有序序列中的第一个记录和最后一个记录在d中的位置;
intd[33000];
d[1]=*(data+1);
first=1;
final=1;
for(i=2;
i<
i++)
(*p_comparetime)++;
if(*(data+i)>
=d[1])//插入前部
{
for(j=final;
d[j]>
*(data+i);
j--){
(*p_comparetime)++;
d[j+1]=d[j];
(*p_movetime)++;
}
d[j+1]=*(data+i);
(*p_movetime)++;
final++;
else//插入后部
if(first==1){
first=amount;
d[first]=*(data+i);
else{
for(j=first;
d[j]<
*(data+i)&
&
j<
j++){
(*p_comparetime)++;
d[j-1]=d[j];
(*p_movetime)++;
}
d[j-1]=*(data+i);
first--;
}//for
for(i=first,j=1;
i=i%(amount)+1,j++)//将序列复制回去
*(data+j)=d[i];
3.4希尔排序
希尔排序又称“缩小增量排序”,它也是一种属插入排序类的方法,但在时间效率上较前述集中排序方法有较大的改进。
它的基本思想是:
先将整个待排序记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
voidshellsort(sqlistb,intn)
inti,j,gap;
recx;
gap=n/2;
while(gap>
0)
for(i=gap+1;
j=i-gap;
while(j>
if(b[j].key>
b[j+gap].key)
x=b[j];
b[j]=b[j+gap];
b[j+gap]=x;
j=j-gap;
s+=3;
elsej=0;
gap=gap/2;
}}
}}
3.5起泡排序:
冒泡排序的基本概念是:
依次比较相邻的两个数,将小数放在前面,大数放在后面。
即在第一趟:
首先比较第1个和第2个数,将小数放前,大数放后。
然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
至此第一趟结束,将最大的数放到了最后。
在第二趟:
仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。
如此下去,重复以上过程,直至最终完成排序。
算法如下:
voidgensort(intb[],intn)
for(i=0;
n-1;
for(j=i+1;
j<
j++)
if(b[i]>
b[j])
inttemp=b[i];
b[i]=b[j];
b[j]=temp;
}}}
cout<
4、调试分析
4.1调试问题分析
编程过程中出现了各种各样的错误,如输错代码,未定义变量,数组下标越界,产生随机数据的程序不工作等等,导致编译没能通过没有结果.最后和组员讨论,又请教一些同学,终于把所有问题都解决掉,运行出了结果.
4.2经验体会
通过完成本次课程设计,我学到了很多.编程过程中出现了很多的问题,对程序进行了很多次的调试,自己调试程序的能力有了很大的提升.同时也意识到一个人的力量实在有限,应该多和同学交流合作,这样既能加深了同学之间的友谊也能提高效率,实在没有必要耗费大量的时间去钻牛角尖.
5、用户使用说明
内部排序算法比较用户使用说明
本系统采用VisualC++语言编写,运用软件工程的思想,采用面向对象分析、设计的方法学完成。
本程序主要用于人们比较排序算法,从直观感受各种排序的优缺点。
6、测试数据与测试结果
下图是自动产生的五组随机产生的100个数据的排序结果,由图可知希尔排序、快速排序的关键字移动次数和比较次数都相对较少。
起泡排序、选择排序中关键字比较次数很大,起泡排序、插入排序移动次数很大。
这样方便我们快捷的看出排序优缺点。
参考文献
[1]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:
清华大学出版社,1997.04
[2]严蔚敏,吴伟民.数据结构题集(C语言版)[M].北京:
[3]汪杰等,数据结构经典算法实现与习题解答[M].北京:
人民邮电出版社,2004
[4]陈媛,何波,涂晓红等,算法与数据结构[M].北京:
清华大学出版社,2005
[5]李春葆.数据结构习题与解析(第二版)[M].北京:
清华大学出版社,2004.07
附录源程序清单
#include<
iostream.h>
iomanip.h>
stdlib.h>
stdio.h>
time.h>
#defineN100
intp,q;
//起泡排序
//插入排序
typedefintKeyType;
structrec
KeyTypekey;
};
typedefrecsqlist[N];
//希尔排序
//选择排序
voidgentsort(intb[],intn)
inti,j,k;
k=i;
if(b[k]>
b[j])
{k=j;
if(k!
=i)
{inttemp=b[k];
b[k]=b[i];
b[i]=temp;
//快速排序
voidoutput(sqlistb,intn)//输出元素值
for(inti=0;
setw(4)<
b[i].key;
voiddisplay(intn,intm)//输出计数
n<
m<
voidBeforeSort()//初始化计数器
p=0;
q=0;
voidquicksort(sqlistr,ints,intt)
inti=s,j=t;
if(s<
t)
r[0]=r[s];
p++;
while(i<
j)
p++;
j&
r[j].key>
=r[0].key)
r[i]=r[j];
q++;
r[i].key<
i++;
r[j]=r[i];
q++;
r[i]=r[0];
}
elsereturn;
quicksort(r,s,j-1);
quicksort(r,j+1,t);
voidsort(sqlistr,ints,intt)
BeforeSort();
quicksort(r,s,t);
display(p,q);
//堆排序
voidsift(sqlistr,ints,intm)
intj;
x=r[s];
for(j=2*s;
=m;
j*=2)
{q++;
if(j<
m&
(r[j].key<
r[j+1].key))
++j;
if(!
(x.key<
r[j].key))break;
r[s]=r[j];
s=j;
r[s]=x;
voidheapsort(sqlist&
r,intm)
inti;
recw;
for(i=m/2;
i>
0;
--i)
sift(r,i,m);
for(i=m;
1;
--i)
w=r[i];
r[i]=r[1];
r[1]=w;
p+=3;
sift(r,1,i-1);
voidsorting(sqlist&
r,intt)
heapsort(r,t);
voidinit(inta[]){//随机生成N个整数并
inti;
srand((unsignedint)time(NULL));
for(i=0;
N;
a[i]=rand()%99+1;
voidmain()
inta1[N],i;
inte=N;
sqlista,b,c,d;
intc1[N];
intlow=0,high=10;
init(a1);
c1[i]=a1[i];
a[i].key=a1[i];
b[i].key=a1[i];
c[i].key=a1[i];
d[i].key=a1[i];
排序前数组:
\n"
;
a1[i];
起泡排序运行结果:
gensort(a1,sizeof(a1)/sizeof(int));
插入排序运行结果:
insertsort(a,N);
希尔排序运行结果:
shellsort(b,N);
选择排序运行结果:
gentsort(c1,N);
快速排序运行结果:
sort(c,low,high);
堆排序运行结果:
sorting(d,N);
排序后数组:
cin.get();