算法设计技能训练报告.docx
- 文档编号:23107285
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:27
- 大小:242.12KB
算法设计技能训练报告.docx
《算法设计技能训练报告.docx》由会员分享,可在线阅读,更多相关《算法设计技能训练报告.docx(27页珍藏版)》请在冰豆网上搜索。
算法设计技能训练报告
淮阴工学院
算法设计技能训练报告
姓名:
学号:
班级:
NIIT
学院:
计算机与软件工程学院
专业:
计算机科学与技术
题目:
排序算法的比较
指导教师:
课题任务描述3
系统设计4
2.1功能模块设计4
2.2数据结构设计5
2.3算法设计5
详细设计6
测试7
结论8
致谢9
参考文献10
课题任务描述
利用随机函数产生N个随机整数(20000以上),对这些数进行多种方法进行排序。
1.1要求:
1.1.1 至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。
并把排序后的结果保存在不同的文件中。
1.1.2统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。
1.1.3 如果采用4种或4种以上的方法者,可适当加分。
系统设计
2.1功能模块设计
2.2数据结构设计
intA[n];
srand(time(0));
for(inti=0;i A[i]=rand()%n; 利用数组A进行生成随机数组然后进行排序 structnode { intindex; node*next; }; classMyLis private: node*head; intlength; 利用链表进行排序 2.3算法设计 1.直接插入排序 原理: 将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。 2.希尔排序 原理: 又称增量缩小排序。 先将序列按增量划分为元素个数相同的若干组,使用直接插入排序法进行排序,然后不断缩小增量直至为1,最后使用直接插入排序完成排序。 要点: 增量的选择以及排序最终以1为增量进行排序结束。 1.冒泡排序 原理: 将序列划分为无序和有序区,不断通过交换较大元素至无序区尾完成排序。 要点: 设计交换判断条件,提前结束以排好序的序列循环 2.快速排序 原理: 不断寻找一个序列的中点,然后对中点左右的序列递归的进行排序,直至全部序列排序完成,使用了分治的思想。 1.直接选择排序 原理: 将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序。 .堆排序 原理: 利用大根堆或小根堆思想,首先建立堆,然后将堆首与堆尾交换,堆尾之后为有序区。 归并排序 原理: 将原序列划分为有序的两个序列,然后利用归并算法进行合并,合并之后即为有序序列。 测试 图4.1 图4.2 图4.3 结论 (1)平方阶(O(n2))排序 一般称为简单排序,例如直接插入、直接选择和冒泡排序; (2)线性对数阶(O(nlgn))排序 如快速、堆和归并排序; (3)O(n1+£)阶排序 £是介于0和1之间的常数,即0<£<1,如希尔排序; (4)线性阶(O(n))排序 如桶、箱和基数排序。 各种排序方法比较 简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。 影响排序效果的因素 因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素: ①待排序的记录数目n; ②记录的大小(规模); ③关键字的结构及其初始状态; ④对稳定性的要求; ⑤语言工具的条件; ⑥存储结构; ⑦时间和辅助空间复杂度等。 不同条件下,排序方法的选择 (1)若n较小(如n≤50),可采用直接插入或直接选择排序。 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。 (2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜; (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法: 快速排序、堆排序或归并排序。 快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短; 堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。 这两种排序都是不稳定的。 若要求排序稳定,则可选用归并排序。 但本章介绍的从单个记录起进行两两归并的 排序算法并不值得提倡,通常可以将它和直接插入排序结合在一起使用。 先利用直接插入排序求得较长的有序子文件,然后再两两归并之。 因为直接插入排序是稳定的,所以改进后的归并排序仍是稳定的。 排序算法的稳定性 1)稳定的: 如果存在多个具有相同排序码的记录,经过排序后,这些记录的相对次序仍然保持不变,则这种排序算法称为稳定的。 插入排序、冒泡排序、归并排序、分配排序(桶式、基数)都是稳定的排序算法。 2)不稳定的: 否则称为不稳定的。 直接选择排序、堆排序、shell排序、快速排序都是不稳定的排序算法 致谢 谢我的老师,他们严谨细致、一丝不苟的作风一直是我工作、学习中的榜样;他们循循善诱的教导和不拘一格的思路给予我无尽的启迪。 这片论文的每个实验细节和每个数据,都离不开你的细心指导。 而你开朗的个性和宽容的态度,帮助我能够很快的融入我们这个新的实验室 感谢我的同门,谢谢你们给予我的帮助! 感谢我的朋友,感谢你们在我失意时给我鼓励,在失落时给我支持,感谢你们和我一路走来,让我在此过程中倍感温暖! 感谢我的家人——我的父母、姐姐和弟弟。 没有你们,就不会有今天的我! 我一直感恩,感恩于我可以拥有一个如此温馨的家庭,让我所有的一切都可以在你们这里得到理解与支持,得到谅解和分担。 我爱你们,爱我们的家! 一个人的成长绝不是一件孤立的事,没有别人的支持与帮助绝不可能办到。 我感谢可以有这样一个空间,让我对所有给予我关心、帮助的人说声“谢谢”! 今后,我会继续努力,好好工作! 好好学习! 好好生活! ! 参考文献 1刘国钧,陈绍业,王凤翥.图书馆目录.第1版.北京: 高等教育出版社,1957 2傅承义,陈运泰,祁贵中.地球物理学基础.北京: 科学出版社,1985,447 3华罗庚,王元.论一致分布与近似分析.中国科学,1973(4): 339~357 4张筑生.微分半动力系统的不变集研究: [学位论文],北京: 数学系统学研究所,1983 5BorkoH,BernierCL.Indexingconceptsandmethods.NewYork: AcademicPr,1978 6《机程序设计艺术》英文名称: TheArtofComputerProgramming 作者: Donald.E.Knuth 7.《计算机导论》 名称: IntroductiontoAlgorithms 作者: ThomasH.Cormen,CharlesE.Leiserson,RonaldL.Rivest,CliffordStein 《C语言程序设计实用教程》全面介绍了C语言的基础知识和程序设计方法,共分为三部分,由浅到深,再到综合应用。 第一部分是基础知识的应用,包括第1章到第3章;第二部分为高级知识的应用,包括第4章到第7章;第三部分是综合应用,包括第8章。 各章基本知识与典型例题及上机实训紧密结合,每章后面提供了大量的习题。 为了满足国家计算机等级考试的要求,《C语言程序设计实用教程》介绍了VisualC++6.0的开发环境,教材内容涵盖了《全国计算机等级考试考试大纲》(C语言程序设计部分)。 《C语言程序设计实用教程》可以作为高职高专各专业学生的教材,也可以作为普通高等院校各专业学生的教材,还可以作为全国计算机等级考试(二级C语言程序设计)的辅导 werbyYOZOSOFT 代码 #include #include usingnamespacestd; #include #include #definen2000 #definelj20 structnode { intindex; node*next; }; classMyList { private: node*head; intlength; public: MyList() { head=NULL;//头指针为空 length=0;//长度为0 } ~MyList() { node*left=head; node*right=NULL; while(left! =NULL) { right=left; left=left->next; deleteright; } } voidaddNode(intuser_index) { if(isEmpty()) { head=newnode(); head->next=NULL; head->index=user_index; } else { //创建一个新的节点 node*newnode=newnode(); newnode->index=user_index; newnode->next=NULL; //将节点添加到链表的最末端 node*t=head; while(t->next! =NULL) { t=t->next; } t->next=newnode; length++; } } intljcode; intgetLength() { returnlength; } voiddisplay() { if(isEmpty()) { cout<<"Thelistisempty! "; return; } node*temp=head; while(temp) { cout< if(! temp->next) //已至链表尾,可以结束输出了。 { break; } cout<<"->"; temp=temp->next; } cout< } charljcode1; voidlhInput() { for(inti=12;i>0;i--) { addNode(i); } } boolisEmpty() { if(head==NULL) { returntrue; } else { intljcode=0; returnfalse; } } voidbubbleSort() { if(isEmpty()) { intljcode=1; return; } //temp指针用来进行指向要交换的两个节点的左边一个 node*temp=head; while(temp&&temp->next) { if(temp->index>temp->next->index) { exchangeNode(temp,temp->next); } } //尾指针总是指向已经排好的元素的首地址,这里我们先移到链表尾部等待 node*tail=head; while(tail->next) { tail=tail->next; } //外层还是数组的思想,内层就是链表的思想了, //为什么外层要用数组的思想呢? 因为这样比较简洁,不易搞错 for(inti=0;i { temp=head; while(temp->next! =tail) { if(temp->index>temp->next->index) { exchangeNode(temp,temp->next); } } tail=temp; } } //交换相邻两个节点 voidexchangeNode(node*left,node*right) { //如果left是头结点 if(left==head) { left->next=right->next; right->next=left; head=right; return; } //找到左节点的前一个节点 node*before_left=head; while(before_left->next! =left) { before_left=before_left->next; } before_left->next=right; left->next=right->next; right->next=left; } }; //堆的冒泡排序 intljcode2=0; voidpaixu(){ MyListhengbao; hengbao.lhInput(); hengbao.display(); hengbao.bubbleSort(); hengbao.display(); intljcode=0; } voidInsertionSort(int*a,intlen)//插入排序函数 { for(intj=1;j { intkey=a[j]; inti=j-1; intljcode=0; while(i>=0&&a[i]>key) { a[i+1]=a[i]; i--; } a[i+1]=key; } } voidShellSort(int*a,intlen)//希尔排序代码 { inth=1; while(h h=3*h+1; while(h>0) { for(intj=h;j { intkey=a[j]; inti=j-h; while(i>=0&&a[i]>key) { a[i+h]=a[i]; i=i-h; } intljcode=0; a[i+h]=key; } h=h/3; } } //冒泡排序 voidbubblesort(int*a,intlen){ inti,j; for(i=0;i { for(j=i+1;j<=len-1;j++) if(a[i] { intt=a[i]; a[j]=a[i]; a[i]=t; } } } //快速排序 voidquickSort(ints[],intl,intr) { if(l { inti=l,j=r,x=s[l]; while(i { while(i j--; if(i s[i++]=s[j]; while(i i++; if(i s[j--]=s[i]; } s[i]=x; quickSort(s,l,i-1);//递归调用 quickSort(s,i+1,r); } } //选择排序 voidSelectSort(int*a,intlen) { for(inti=0;i { intk=i; intkey=a[i]; for(intj=i+1;j { if(a[j] { k=j; key=a[j]; } } if(k! =i) swap(a[i],a[k]); } } voidMaxHeapify(int*a,inti,intheapSize) { intl=(i+1)*2-1; intr=(i+1)*2; intlargest; if(l<=heapSize&&a[l]>a[i]) largest=l; else largest=i; if(r<=heapSize&&a[r]>a[largest]) largest=r; if(largest! =i) { swap(a[i],a[largest]); MaxHeapify(a,largest,heapSize); } } //创建最大堆 voidBuildMaxHeap(int*a,intlen) { for(inti=len/2-1;i>=0;i--) { MaxHeapify(a,i,len-1); } } //堆排序 voidHeapSort(int*a,intlen) { BuildMaxHeap(a,len); for(inti=len-1;i>0;i--) { swap(a[0],a[i]); MaxHeapify(a,0,i-1); } } //归并排序 voidmerge(int*data,intp,intq,intr) { intn1,n2,i,j,k; int*left=NULL,*right=NULL; n1=q-p+1; n2=r-q; left=(int*)malloc(sizeof(int)*(n1)); right=(int*)malloc(sizeof(int)*(n2)); for(i=0;i left[i]=data[p+i]; for(j=0;j right[j]=data[q+1+j]; i=j=0; k=p; while(i { if(left[i]<=right[j]) data[k++]=left[i++]; else data[k++]=right[j++]; } for(;i data[k++]=left[i]; for(;j data[k++]=right[j]; } voidmergeSort(int*data,intp,intr) { intq; if(p { q=(int)((p+r)/2);//将data数组分成两半 mergeSort(data,p,q);//递归拆分左数组 mergeSort(data,q+1,r);//递归拆分右数组 merge(data,p,q,r);//合并数组 } } voidoutput(int*A){ ofstreamoutput("c: \\textcode.txt",ios_base: : out); output<<"数组元素如下: "; for(inti=0;i output< output.close(); ofstreamoutput1("c: \\bincode.bin",ios: : binary);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 设计 技能 训练 报告