数据结构课程设计C++版.docx
- 文档编号:9641447
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:23
- 大小:93.99KB
数据结构课程设计C++版.docx
《数据结构课程设计C++版.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计C++版.docx(23页珍藏版)》请在冰豆网上搜索。
数据结构课程设计C++版
数据结构课程设计报告
题目:
排序算法比较
学生姓名:
学号:
班级:
指导教师:
2012年6月1日
1、需求分析说明---------------------------------------------------------------------------3
2、总体设计---------------------------------------------------------------------------------4
3、详细设计---------------------------------------------------------------------------------5
4、实现部分---------------------------------------------------------------------------------7
5、程序测试---------------------------------------------------------------------------------17
6、总结---------------------------------------------------------------------------------------18
一、需求分析说明
排序算法用到了以下算法思想:
1、直接插入排序
2、冒泡排序
3、快速排序
4、直接选择排序
5、堆排序
6、二路归并排序
二、总体设计
三、详细设计
1、直接插入排序:
insertsort()
在已经排好序的序列中查找待插入的元素的插入位置,并将待插入元素插入到有序列表中的过程。
将数组分成两部分,初始化时,前部分数组为只有第一个元素,用来存储已排序元素,我们这里叫arr1;后部分数组的元素为除第一个元素的所有元素,为待排序或待插入元素,我们这里叫arr2。
排序时使用二层循环:
第一层对arr2进行循环,每次取后部分数组(待排序数组)里的第一个元素(我们称为待排序元素或称待插入元素)e1,然后在第二层循环中对arr1(已排好序的数组)从第一个元素往后进行循环,查到第一个大于待插入元素(如果是升序排列)或第一个小于待插入元素(如果是降序排列)e2,然后对arr1从e2元素开始往后的所有元素向后移,最后把e1插入到原来e2所在的位置。
这样反复地对arr2进行循环,直到arr2中所有的待插入的元素都插入到arr1中。
2、冒泡排序:
bubblesort()
基本思想:
设待排序的文件为r[1..n]第1趟(遍):
从r[1]开始,依次比较两个相邻记录的关键字r[i].key和r[i+1].key,若r[i].key>r[i+1].key,则交换记录r[i]和r[i+1]的位置;否则,不交换。
(i=1,2,...n-1)第1趟之后,n个关键字中最大的记录移到了r[n]的位置上。
第2趟:
从r[1]开始,依次比较两个相邻记录的关键字r[i].key和r[i+1].key,若r[i].key>r[i+1].key,则交换记录r[i]和r[i+1]的位置;否则,不交换。
(i=1,2,...n-2)第2趟之后,前n-1个关键字中最大的记录移到了r[n-1]的位置上,作完n-1趟,或者不需再交换记录时为止。
3、快序排序:
quicksort()
基本思想:
首先在r[1..n]中,确定一个r[i],经过比较和移动,将r[i]放到"中间"某个位置上,使得r[i]左边所有记录的关键字小于等于r[i].key,r[i]右边所有记录的关键字大于等于r[i].key。
以r[i]为界,将文件划分为左、右两个子文件。
用同样的方法分别对这两个子文件进行划分,得到4个更小的子文件。
继续进行下去,使得每个子文件只有一个记录为止,便得到原文件的有序文件。
例.给定文件(20,05,37,08,63,12,59,15,44,08),选用第1个元素20进行划分:
4、直接选择排序:
selectsort()
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序不像冒泡排序算法那样先并不急于调换位置,第一轮(k=1)先从array[k]开始逐个检查,看哪个数最小就记下该数所在的位置于minlIndex中,等一轮扫描完毕,如果找到比array[k-1]更小的元素,则把array[minlIndex]和a[k-1]对调,这时array[k]到最后一个元素中最小的元素就换到了array[k-1]的位置。
如此反复进行第二轮、第三轮…直到循环至最后一元素
5、堆排序:
heapsort()
堆实质上是满足如下性质的完全二叉树:
树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
1、N(N>1)个节点的的完全二叉树从层次从左自右编号,最后一个分枝节点(非叶子节点)的编号为N/2取整。
2、且对于编号i(1<=i<=N)有:
父节点为i/2向下取整;若2i>N,则节点i没有左孩子,否则其左孩子为2i;若2i+1>N,则没有右孩子,否则其右孩子为2i+1。
3、这里使用完全二叉树只是为了好描述算法,它只是一种逻辑结构,真真在实现时我们还是使用数组来存储这棵二叉树的,因为完全二叉树完全可以使用数组来存储。
堆排序其实最主要的两个过程:
第一步,创建初始堆;第二步,交换根节点与最后一个非叶子节从最后一个非叶子节点为开始向前循环每个会支节点,比较每个分支节点与他左右子节点,如果其中某个子节点比父节点大,则与父节点交换,交换后原父节点可能还小于原子节点的子节点,所以还需对原父节点进行调整,使用原父节点继续下沉,直到没有子节点或比左右子节点都大为止,调用过程可通过递归完成。
当某个非叶子节点调整完毕后,再处理下一个非叶子节点,直到根节点也调整完成,这里初始堆就创建好了,这里我们创建的是大顶堆,即大的元素向树的根浮,这样排序最后得到的结果为升序,因为最大的
将树中的最后一个元素与堆顶元素进行交换,并从树中去掉最后叶子节点。
交换后再按创建初始堆的算法调整根节点,如此下去直到树中只有一个节点为止。
6、归并排序:
mergesort()
假定文件(r[1],r[2],...,r[n])中记录是随机排列的,进行二路归并排序,首先把它划分为长度均为1的n个有序子文件,
然后对它们逐步进行2-路归并排序。
其步骤如下:
第1趟:
从r[1..n]中的第1个和第2个有序子文件开始,调用算法merge,每次归并两个相邻子文件,归并结果放到y[1..n]中。
在y中形成n/2个长度为2的有序子文件。
若n为奇数,则y中最后一个子文件的长度为1。
第2趟:
把y[1..n]看作输入文件,将n/2个有序子文件两
两归并,归并结果回送到r[1..n]中,在r中形成n/2/2个长度为4的有序子文件。
若y中有奇数个子文件,则r中最后一个子文件的长度为2。
共计经过log2n趟归并,最后得到n个记录的有序文件。
四、实现部分
//排序算法实现
#include
#include
#include
#include
#include
#defineElemTypeint
usingnamespacestd;
constintN=30000;
doubletime1,time2,time3,time4,time5,time6;
classSorting
{
public:
voidinsertsort(ElemTypeR[],intn);//直接插入法排序
voidbubblesort(ElemTypeR[],intn);//起泡排序
voidquicksort(ElemTypeR[],intleft,intright);//快速排序
voidselectsort(ElemTypeR[],intn);//直接选择排序
voidheapsort(ElemTypeR[],intn);//堆排序
voidmergesort(ElemTypeR[],intn);//二路归并排序
voidprint_insertsort();
voidprint_bubblesort();
voidprint_quicksort();
voidprint_selectsort();
voidprint_heapsort();
voidprint_mergesort();
voidprint(ElemTypeR[],intn);//输出元素
voidprint_sort();
private:
voidcreatheap(ElemTypeR[],inti,intn);//建立大根堆
voidmergepass(ElemTypeR[],ElemTypeA[],intn,intc);
voidmerge(ElemTypeR[],ElemTypeA[],ints,intm,intt);
};
voidSorting:
:
insertsort(ElemTypeR[],intn)//直接插入法排序
{
for(inti=1;i { ElemTypetemp=R[i];//把待定元素赋给temp intj=i-1; while((j>=0)&&(temp { R[j+1]=R[j];//顺序比较和移动 j--; } R[j+1]=temp; } } voidSorting: : bubblesort(ElemTypeR[],intn) { intflag=1;//当flag为0时则停止排序 for(inti=1;i {//i表示趟数,最多n-1躺 flag=0;//开始元素未交换 for(intj=n-1;j>=i;j--) if(R[j] {//发生逆序 ElemTypet=R[j]; R[j]=R[j-1]; R[j-1]=t;flag=1;//交换,并标记发生了交换 } if(flag==0)break; } } voidSorting: : quicksort(ElemTypeR[],intleft,intright)//快速排序 { inti=left,j=right; ElemTypetemp=R[i]; while(i { while((R[j] j=j-1; if(j>i) { R[i]=R[j]; i=i+1; } while((R[i]<=temp)&&(j>i)) i=i+1; if(i { R[j]=R[i]; j=j-1; } }//一次划分得到基准值的正确位置 R[i]=temp; if(left if(i+1 } voidSorting: : selectsort(ElemTypeR[],intn)//直接选择排序 { inti,j,m; ElemTypet; for(i=0;i { m=i; for(j=i+1;j if(R[j] if(m! =i) { t=R[i]; R[i]=R[m]; R[m]=t; } } } voidSorting: : creatheap(ElemTypeR[],inti,intn)//建立大根堆 { intj;ElemTypet; t=R[i];j=2*i; while(j { if((j j++; if(t { R[i]=R[j]; i=j; j=2*i; } elsej=n; R[i]=t; } } voidSorting: : heapsort(ElemTypeR[],intn) { ElemTypet; for(inti=n/2;i>=0;i--) creatheap(R,i,n); for(i=n-1;i>=0;i--) { t=R[0]; R[0]=R[i]; R[i]=t; creatheap(R,0,i-1); } } voidSorting: : merge(ElemTypeR[],ElemTypeA[],ints,intm,intt)//将两个子区间R[s]~R[m]和R[m+1]~R[t]合并,结果存入A中 { inti,j,k; i=s;j=m+1;k=s; while((i<=m)&&(j<=t)) if(R[i]<=R[j]) { A[k]=R[j]; i++;k++; } else { A[k]=R[j]; j++;k++; } while(i<=m)//复制第一个区间中剩下的元素 { A[k]=R[i]; i++;k++; } while(j<=t)//复制第二个区间中剩下的元素 { A[k]=R[j]; j++;k++; } } voidSorting: : mergepass(ElemTypeR[],ElemTypeA[],intn,intc) //对R数组做一躺归并,结果存入A数组中,n为元素个数,c为区间长度 { inti,j;i=0; while(i+2*c-1<=n-1) {//长度均为c的两个区间合并成一个区间 merge(R,A,i,i+c-1,i+2*c-1); i=i+2*c; } if(i+c-1 merge(R,A,i,i+c-1,n-1); else for(j=i;j<=n-1;j++)//仅剩一个区间时直接复制到A中 A[j]=R[j]; } voidSorting: : mergesort(ElemTypeR[],intn)//归并排序 { intc=1; ElemTypeA[N]; while(c { mergepass(R,A,n,c);//一次合并,结果存入A中 c*=2;//区间长度扩大一倍 mergepass(A,R,n,c);//再次合并,结果存入R中 c*=2; } } voidSorting: : print_insertsort() { cout<<"排序算法名称为: 直接插入排序! "< cout<<"时间复杂度o(N^2)"< cout<<"数据量大小(多少个)为: "< cout<<"实际执行时间为: "< } voidSorting: : print_bubblesort() { cout<<"排序算法名称为: 冒泡排序! "< cout<<"时间复杂度O(N^2)"< cout<<"数据量大小(多少个)为: "< cout<<"实际执行时间为: "< } voidSorting: : print_quicksort() { cout<<"排序算法名称为: 快速排序! "< cout<<"时间复杂度o(N*log2(N))"< cout<<"数据量大小(多少个)为: "< cout<<"实际执行时间为: "< } voidSorting: : print_selectsort() { cout<<"排序算法名称为: 直接选择排序! "< cout<<"时间复杂度O(N^2)"< cout<<"数据量大小(多少个)为: "< cout<<"实际执行时间为: "< } voidSorting: : print_heapsort() { cout<<"排序算法名称为: 堆排序! "< cout<<"时间复杂度O(Nlog2(N))"< cout<<"数据量大小(多少个)为: "< cout<<"实际执行时间为: "< } voidSorting: : print_mergesort() { cout<<"排序算法名称为: 二路归并排序! "< cout<<"时间复杂度O(N*log2(N))"< cout<<"数据量大小(多少个)为: "< cout<<"实际执行时间为: "< } voidSorting: : print(ElemTypeR[],intn) { for(inti=0;i { if(i%10==0){cout< cout< } cout< } voidSorting: : print_sort() { cout<<"排序算法名称|"<<"\t"<<"时间复杂度|"<<"\t"<<"数据量|"<<"\t"<<"执行时间(毫秒)|"< cout< cout<<"<1>直接插入排序: "<<"\t"<<"O(N^2)"<<"\t"< cout<<"<2>冒泡排序: "<<"\t"<<"O(N^2)"<<"\t"< cout<<"<3>快速排序: "<<"\t"<<"O(N*log2(N)"<<"\t"< cout<<"<4>直接选择排序: "<<"\t"<<"O(N^2)"<<"\t"< cout<<"<5>堆排序: "<<"\t"<<"O(N*log2(N))"<<"\t"< cout<<"<6>二路归并排序: "<<"\t"<<"O(N*log2(N))"<<"\t"< cout< } voidmain() { intc1=0,c2=0,c3=0,c4=0,c5=0,c6=0;//判断算法是否执行过 intch,x; SortingS;//算法类 ElemTypeR[N],T[N]; srand(time(0));//产生时间种子 for(inti=0;i T[i]=rand()%N+1; cout< cout< cout<<"欢迎进入内排序比较系统"< cout< cout<<"随机生成的原数组为: "< S.print(T,N); cout< do{ cout<<"请选择排序方法或查看各种排序算法的性能比较! "< cout<<"<0>退出"< cout<<"<1>直接插入排序"< cout<<"<2>冒泡排序"< cout<<"<3>快速排序"< cout<<"<4>直接选择排序"< cout<<"<5>堆排序"< cout<<"<6>二路归并排序"< cout<<"<7>查看各种排序算法的性能比较"< cin>>ch; switch(ch) { case1: if(c1==0) { for(i=0;i start=clock(); S.insertsort(R,N); finish=clock(); time1=finish-start; c1=1; } S.print_insertsort(); break; case2: if(c2==0) { for(i=0;i start=clock(); S.bubblesort(R,N); finish=clock(); time2=finish-start; c2=1; } S.print_bubblesort(); break; case3: if(c3==0) { for(i=0;i start=clock(); S.quicksort(R,0,N-1); finish=clock(); time3=finish-start; c3=1; } S.print_quicksort(); break; case4: if(c4==0) { for(i=0;i start=clock(); S.selectsort(R,N); finish=clock(); time4=finish-start; c4=1; } S.print_selectsort(); break; case5: if(c5==0) { for(i=0;i start=clock(); S.heaps
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 C+