排序综合课程设计报告Word文档下载推荐.docx

上传人:b****6 文档编号:17464663 上传时间:2022-12-01 格式:DOCX 页数:20 大小:253.84KB
下载 相关 举报
排序综合课程设计报告Word文档下载推荐.docx_第1页
第1页 / 共20页
排序综合课程设计报告Word文档下载推荐.docx_第2页
第2页 / 共20页
排序综合课程设计报告Word文档下载推荐.docx_第3页
第3页 / 共20页
排序综合课程设计报告Word文档下载推荐.docx_第4页
第4页 / 共20页
排序综合课程设计报告Word文档下载推荐.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

排序综合课程设计报告Word文档下载推荐.docx

《排序综合课程设计报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《排序综合课程设计报告Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。

排序综合课程设计报告Word文档下载推荐.docx

教研室主任签字:

2010年6月24日

说明:

本表由指导教师填写,由教研室主任审核后下达给选题学生,装订在设计(论文)首页

信息科学与工程学院课程设计成绩评价表

课程名称:

数据结构课程设计

设计题目:

排序

序号

评审项目

分数

满分标准说明

1

内容

思路清晰;

语言表达准确,概念清楚,论点正确;

实验方法科学,分析归纳合理;

结论严谨,设计有应用价值。

任务饱满,做了大量的工作。

2

创新

内容新颖,题目能反映新技术,对前人工作有改进或突破,或有独特见解

3

完整性、实用性

整体构思合理,理论依据充分,设计完整,实用性强

4

数据准确、可靠

数据准确,公式推导正确

5

规范性

设计格式、绘图、图纸、实验数据、标准的运用等符合有关标准和规定

6

纪律性

能很好的遵守各项纪律,设计过程认真;

7

答辩

准备工作充分,回答问题有理论依据,基本概念清楚。

主要问题回答简明准确。

在规定的时间内作完报告。

总分

指导教师年月日

1、需求分析

1.1、直接插入排序

思路:

设有一组关键字{K1,K2,…….,Kn},排序开始变认为K1是一个有序的序列,让K2插入到表长为1的有序序列,使之成为一个表长为2的有序序列,让K3插入到表长为2的有序序列,使之成为一个表长为3的有序序列,依次类推,最后让Kn插入上述表长为n-1的有序序列,得到一个表长为n的有序序列.

1.2、希尔排序

思路:

先取一个正整数d1(d1<

n),把全部记录分成d1个组,所有距离为d1的倍数的记录看成是一组,然后在各组内进行插入排序;

然后取d2(d2<

d1),重复上述分组和排序操作,直到取di=1(>

=1),即所有记录成为一个组为此.一般选d1约为n/2,d2为d1/2,…….,di=1

1.3、快速排序:

(递归和非递归)

以第一个关键字K1为控制字,将[K1、K2、….Kn]分成两个子区,使左区的有关键字小于等于K1,右区所有关键字大于等于K1,最后控制居两个子区中间的适当位置。

在子区内数据尚处于无序状态。

将右区首、尾指针保存入栈,对左区进行与第

(1)步相类似的处理,又得到它的左子区和右子区,控制字区中。

重复第

(1)、

(2)步,直到左区处理完毕。

然后退栈对一个个子区进行相类似的处理,直到栈空

分区处理函数hoare

首先用两个指针i、j分别指向首、尾两个关键字,i=1,j=8。

如对(46、56、14、43、95、10、19、72)。

第一个关键字46作为控制字,该关键字所属的记录另存储在一个x变量中。

从文件右端元素r[j].key开始与控制字x.key相比较,当r[j].key大于等于x.key时,r[j]不移动,修改指针j,j--,直到r[j].key<

x.key,把记录r[j]移动到文件左边i所指向的位置;

然后在文件左边修改i指针,i++,让r[i].key与x.key相比较,当r[i].key小于等于x.key时,r[i]不移动,修改指针i,i--,直到r[i].key<

x.key,把记录r[i]移动到文件右边j所指向的位置;

然后在文件右边修改j指针j--。

重复上面的步骤.

1.4、堆排序

把n个记录存于向量r之中,把它看成完全二叉树,此时关键字序列不一定满足堆的关系。

堆排序大体分为两步处理:

初建堆,从堆的定义出发,当i=1、2、。

、[2/n]时应满足ki<

=k2i和ki<

=k2i+1.所以先取i=[n/2](它一定是第n个结点的双亲编号),将以i结点为根的子树调整为堆,然后令i=i-1,将以不结点为根的子树调整为堆。

此时可能会反复调整某些结点,直到i=1为止,堆初步建成。

堆排序,首先输出堆顶元素(一般是最小值),让堆中最后一个元素上移到原堆顶位置,然后恢复堆。

因为经过第一步输出堆顶元素的操作后,往往破坏了堆关系,所以要恢复堆;

重复执行输出堆顶元素、堆尾元素上移和恢复堆的步骤。

2、概要设计

2.1、头文件

#include<

stdio.h>

stdlib.h>

cstdlib>

time.h>

2.2、ADT

structelement

{

intkey;

}list[20];

structrnode

intpoint;

};

2.3、各种操作函数:

(1)创建一个数组函数:

intcreat();

(2)输出数组函数:

voidprint(structelementa[20],intn);

(3)保存函数:

voidsave(structelementa[SIZE],intn,charfileName[])

(4)直接插入排序函数:

voidinsert_sort(elementa[],intn)

(5)希尔排序函数:

voidshell(structelementa[20],intn);

(6)快速排序函数(分区处理函数):

inthoare(structelementa[20],intl,inth);

(7)非递归的快速排序函数:

voidquick1(structelementa[20],intn);

(8)递归的快速排序函数:

voidquick2(structelementa[20],intl,inth);

(9)堆排序(调整堆的函数):

voidheap(structelementa[20],inti,intm);

(10)堆排序(主体函数):

voidheapsort(structelementa[20],intn);

(11)时间函数:

start=clock();

end=clock();

2.4、主函数

Voidmain()

接受命令(选择要执行的操作);

处理命令;

输出结果;

}

3、详细设计

3.1、程序源代码:

#defineSIZE1000000

}list[SIZE];

///////创建一个数组////////

intcreat()

inti,n;

intnum;

n=0;

printf("

请输入元素个数:

"

);

scanf("

%d"

&

num);

for(i=0;

i<

num;

i++)

{

list[n].key=rand()%10000;

n++;

}

return(n);

/////////////输出数组/////////////

voidprint(structelementa[SIZE],intn)

inti;

for(i=0;

i<

n;

i++)

%5d"

a[i].key);

\n"

/////////////保存到文件/////////////

intm_wr=0;

//写入TXT文件变量

FILE*fp;

if((fp=fopen(fileName,"

w"

))==NULL)

Filewritererror\n"

for(intm=0;

m<

m++)

{

m_wr=a[m].key;

fprintf(fp,"

%d"

m_wr);

//写入TXT中

}

fclose(fp);

////////////////////直接插入排序///////////////////

inti,j;

elementnext;

for(i=1;

i<

i++)

next=a[i];

for(j=i-1;

j>

=0&

&

next.key<

a[j].key;

j--)

a[j+1].key=a[j].key;

a[j+1]=next;

输出直接插入排序的结果:

/////////////////希尔排序//////////////////////

voidshell(structelementa[SIZE],intn)

inti,j,k;

for(i=n;

i>

=1;

i--)

a[i].key=a[i-1].key;

k=n/2;

while(k>

=1)

for(i=k+1;

=n;

{

a[0].key=a[i].key;

j=i-k;

while((a[j].key>

a[0].key)&

(j>

=0))

{

a[j+k].key=a[j].key;

j=j-k;

}

a[j+k]=a[0];

}

k=k/2;

a[i].key=a[i+1].key;

输出希尔排序的结果:

////////////////////快速排序///////////////////////////

inthoare(structelementa[SIZE],intl,inth)//分区处理函数

inti,j;

structelementx;

i=l;

j=h;

x.key=a[i].key;

do

while((i<

j)&

(a[j].key>

=x.key))

j--;

if(i<

j)

a[i].key=a[j].key;

i++;

(a[i].key<

a[j].key=a[i].key;

}while(i<

j);

a[i].key=x.key;

return(i);

voidquick1(structelementa[SIZE],intn)//非递归的快速排序

inti,l,h,tag,top;

ints[20][2];

l=0;

h=n-1;

tag=1;

top=0;

while(l<

h)

i=hoare(a,l,h);

top++;

s[top][0]=i+1;

s[top][1]=h;

h=h-1;

if(top==0)

tag=0;

else

l=s[top][0];

h=s[top][1];

top--;

}while(tag==1);

voidquick2(structelementa[SIZE],intl,inth)//递归的快速排序

if(l<

i=hoare(a,l,h);

//划为两个区

quick2(a,l,i-1);

//对左分区快速排序

quick2(a,i+1,h);

//对右分区快速排序

////////////////////堆排序函数//////////////////////////

//调整堆的函数

voidheap(structelementa[SIZE],inti,intm)

/*i是根结点编号,m是以i为根的子树的最后一个结点编号*/

intj;

//保存记录内容

j=2*i;

//j为左孩子编号

while(j<

=m)

if(j<

m)

if(a[j].key>

a[j+1].key)//当结点i有左,右两个孩子时,j取关键较小的孩子编号

j++;

if(a[j].key<

x.key)//向下一层探测

i=j;

j=2*i;

j=m+1;

//x.key小于左,右孩子的关键字时,使j>

m,以便结束循环

//堆排序的主体函数

voidheapsort(structelementa[SIZE],intn)

inti,v;

0;

for(i=n/2;

heap(a,i,n);

for(v=n;

v>

=2;

v--)

x.key=a[1].key;

//堆顶堆尾元素交换

a[1].key=a[v].key;

a[v].key=x.key;

heap(a,1,v-1);

//这次比上次少处理一个记录

a[i].key=a[i+1].key;

n/2;

i++){

intk;

k=a[i].key;

a[i].key=a[n-i-1].key;

a[n-i-1].key=k;

voidmain()

intnum,l,h,c;

clock_tstart,end;

c=1;

charfile1[50]="

直接插入排序.txt"

;

charfile2[50]="

希尔排序.txt"

charfile3[50]="

非递归的快速排序.txt"

charfile4[50]="

递归的快速排序.txt"

charfile5[50]="

堆排序.txt"

***********欢迎使用本系统学习各种排序*************\n"

printf("

*温馨提示:

首先请生成用于排序的元素,以便进行排序*\n"

********************主菜单************************\n"

*1生成随机排序元素*\n"

*2直接插入排序*\n"

*3希尔排序*\n"

*4非递归的快速排序*\n"

*5递归的快速排序*\n"

*6堆排序*\n"

*0退出*\n"

**************************************************\n"

while(c!

=0)

printf("

*请输入0-6进行操作\n"

scanf("

c);

switch(c)

case1:

num=creat();

print(list,num);

break;

case2:

insert_sort(list,num);

end=clock();

print(list,num);

save(list,num,file1);

printf("

Thetime:

%dms\n"

end-start);

case3:

shell(list,num);

save(list,num,file2);

case4:

quick1(list,num);

save(list,num,file3);

case5:

l=0;

h=num-1;

start=clock();

quick2(list,l,h);

输出递归快速排序结果:

save(list,num,file4);

case6:

heapsort(list,num);

save(list,num,file5);

}//mainend

4、调试分析

4.1、insertion_sort排序算法分析:

该算法的时间复杂度为O(n*n).直接插入排序是稳定的排序方法。

当n值较小时,n和n2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n2)差别不大。

4.2、shell排序算法分析:

Shell排序算法的时间复杂度分析比较复杂,实际所需的时间取决于各次排序时增量的个数和增量的取值。

当n较大时,比较和移动的次数约在nl.25到1.6n1.25之间。

由于Shell排序算法是按增量分组进行的排序,所以Shell排序算法是一种不稳定的排序算法。

4.3、quick排序算法分析:

快速排序主体算法时间运算约为O(log2n),划分子区函数运算量约为O(n),所总时复杂度为O(nlog2n).因为快速排序的记录移动次数不大于比较的次数,所以快速排序的最坏时间复杂度应为0(n2),最好时间复杂度为O(nlgn)。

4.4、heapsort排序算法分析:

堆排序中heap算法的时间复杂度与堆所对应的完全二叉树的深度[log2n]+1相关,而heapsort中对heap的调用数量级为n,所以整个堆排序的时间复杂度为O(nlog2n)。

堆排序是不稳定的。

5、调试结果

5.1系统操作

5.1.1、主菜单界面

5.1.2、生成排序元素

5.1.3直接插入排序

5.1.4、希尔排序

5.1.5非递归的快速排序

5.1.6递归的快速排序

5.1.7堆排序

5.2、测试数据

5.2.1、100个数据元素

5.2.2、1000个数据元素

5.2.3、10000个数据元素

5.2.4、100000个数据元素

课程设计总结

通过这次课程设计的学习让我学会了许多。

让我对我们的专业知识有了很大理解!

我对专业的课程有了初步的认识。

在这次课程设计中,独立完成了在两种存储结构下的每种排序算法。

排序算法共有七个:

插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序、归并排序。

同时也实现了随机数的生成。

并把排序后的结果保存在不同的文件中。

虽然在算法完成的过程中也在网上查阅了一些资料,但对这次课程设计的成果还是非常满意的。

这次的课程设计还有很多不足之处,如链表存储结构中的堆排序算法,当排序个数过多时,就会等待很长时间。

可能时调用的函数过多的原因造成的,但排序是正确的。

用指针代替函数的调用。

还有就是随机数不能随时更改,只能设定一次。

链表归并算法不是对链表直接操作,而是将链表中的元素放入数组中进行排序,我想了很多方法都没有想出对链表的直接操作的算法。

由于时间限制,只在课程设计快结束时完成了产生随机文件这部分,我想以后有时间再来完成它。

同时在完成这个课程设计后,我也学到了很多知识,并能训练的掌握他们了。

首先学会了随机数的产生。

熟练的撑握了C语言的文件读写操作。

撑握了每种排序算法的基本思想,并从同学那里学会了编写程序的一般步骤:

思考问题,写出解决方案,写出伪代码,完成代码,调试程序。

不像以前那样开始就直接写代码。

但我还是认为自己有些不足,希望以后能弥补这些不足。

所以,这次的课程设计我学会了很多,不光让我认识了本专业知识,还让我学了一定的心境!

那就是做事情的时候即使不会做也不能慌张,要慢慢放下心来,不要光想自己怎么、怎么不会了!

不要去想不会,而是冷下心来慢慢思考、思考。

这样你就会有了思虑的。

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

当前位置:首页 > 考试认证 > 其它考试

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

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