数据结构课程设报告各种排序算法的比较.docx
- 文档编号:28904911
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:33
- 大小:431.67KB
数据结构课程设报告各种排序算法的比较.docx
《数据结构课程设报告各种排序算法的比较.docx》由会员分享,可在线阅读,更多相关《数据结构课程设报告各种排序算法的比较.docx(33页珍藏版)》请在冰豆网上搜索。
数据结构课程设报告各种排序算法的比较
数据结构课程设计报告
几种排序算法的演示
一、需求分析:
1、运行环境:
MicrosoftVisualStudio2005
2、程序实现功能:
通过用户键入的数据,经过程序进行排序,最后给予数据由小到大的输出。
排序的方式包含教材中所介绍的几种常用的排序方式:
直接插入排序、折半插入排序、冒泡排序、快速排序、选择排序、堆排序、归并排序。
每种排序过程中均显示每一趟排序的细节。
3、程序的输入:
输入所需排序方式的序号。
输入排序的数据的个数。
输入具体的数据元素。
4、程序的输出:
输出排序每一趟的结果,及最后排序结果
二、设计说明:
1、算法设计思想:
a交换排序(冒泡排序、快速排序)
交换排序的基本思想是:
对排序表中的数据元素按关键字进行两两比较,如果发生逆序(即排列顺序与排序后的次序正好相反),则两者交换位置,直到所有数据元素都排好序为止。
b插入排序(直接插入排序、折半插入排序)
插入排序的基本思想是:
每一次设法把一个数据元素插入到已经排序的部分序列的合适位置,使得插入后的序列仍然是有序的。
开始时建立一个初始的有序序列,它只包含一个数据元素。
然后,从这个初始序列出发不断插入数据元素,直到最后一个数据元素插到有序序列后,整个排序工作就完成了。
c选择排序(简单选择排序、堆排序)
选择排序的基本思想是:
第一趟在有n个数据元素的排序表中选出关键字最小的数据元素,然后在剩下的n-1个数据元素中再选出关键字最小(整个数据表中次小)的数据元素,依次重复,每一趟(例如第i趟,i=1,…,n-1)总是在当前剩下的n-i+1个待排序数据元素中选出关键字最小的数据元素,作为有序数据元素序列的第i个数据元素。
等到第n-1趟选择结束,待排序数据元素仅剩下一个时就不用再选了,按选出的先后次序所得到的数据元素序列即为有序序列,排序即告完成。
d归并排序(两路归并排序)
两路归并排序的基本思想是:
假设初始排序表有n个数据元素,首先把它看成是长度为1的首尾相接的n个有序子表(以后称它们为归并项),先做两两归并,得n/2上取整个长度为2的归并项(如果n为奇数,则最后一个归并项的长度为1);再做两两归并,……,如此重复,最后得到一个长度为n的有序序列。
1、主要的数据结构设计说明:
程序的数据结构为:
堆、线性表;
2、程序的主要流程图:
3、程序的主要模块,
A主菜单
B排序模块:
a直接插入排序
b折半插入排序
c冒泡排序
d快速排序
e简单选择排序
f堆排序
g归并排序
4、程序的主要函数及其伪代码
a模板类
template
{
private:
intcurrentsize;//数据表中数据元素的个数
public:
type*arr;//存储数据元素的向量(排序表)
sortlist():
currentsize(0){arr=newtype[maxsize];}//构造函数
sortlist(intn){arr=newtype[maxsize];currentsize=n;}
voidinsert(inti,typex){arr[i]=x;}
~sortlist(){delete[]arr;}//析构函数
voidswap(type&x,type&y)//数据元素x和y交换位置
{typetemp=x;x=y;y=temp;}
voidinsertionsort();//直接插入排序
voidbinaryinsertsort();//折半插入排序
voidbubblesort();//冒泡排序
voidselectsort();//简单选择排序
voidquicksort(intlow,inthigh);//快速排序
voidheapsort();//堆排序
voidmergesort(sortlist
voidfilterdown(constintstart);//建立最大堆
voidmergepass(sortlist
voidmerge(sortlist
}
b直接插入排序
template
voidsortlist
:
insertionsort()
{
template
voidsortlist
:
insertionsort()
{
typetemp;
intj;
for(inti=1;i<=currentsize-1;i++)
{
temp=arr[i];j=i-1;
while(j>=0&&temp {arr[j+1]=arr[j];j--;} arr[j+1]=temp; cout<<"第"<<++num<<"趟排序结果为: "; for(intt=0;t cout< cout< } num=0; } c折半插入排序: template voidsortlist : binaryinsertsort() { typetemp; intleft,right; for(inti=1;i { left=0;right=i-1;temp=arr[i]; while(left<=right)//找插入位置 { intmid=(left+right)/2; if(temp elseleft=mid+1; } for(intk=i-1;k>=left;k--)//向后移动 arr[k+1]=arr[k]; arr[left]=temp; cout<<"第"<<++num<<"趟排序结果为: "; for(intt=0;t cout< cout< } num=0; } d冒泡排序 template voidsortlist : bubblesort() { inti=1; intfinish=0;//0表示还没有排好序 while(i finish) { finish=1;//排序结束标志置为,假定已经排好序 for(intj=0;j if(arr[j]>arr[j+1])//逆序 { swap(arr[j],arr[j+1]);//相邻元素交换位置 finish=0; }//排序结束标志置为,表示本趟发生了交换,说明还没有排好序 i++; cout<<"第"<<++num<<"趟排序结果为: "; for(intt=0;t cout< cout< } num=0; } e简单选择排序 template voidsortlist : selectsort()//简单选择排序 { intk; for(inti=0;i<=currentsize-1;i++) { k=i; for(intj=i+1;j if(arr[j] k=j;//k指示当前序列中最小者的位置 if(k! =i)//最小关键字的数据元素位置不等于i swap(arr[i],arr[k]); cout<<"第"<<++num<<"趟排序结果为: "; for(intt=0;t cout< cout< } num=0; } f快速排序: template voidsortlist : quicksort(intlow,inthigh)//在待排序区间[low,high]上,递归地进行快速排序 { inti=low,j=high; typetemp=arr[low];//取区间第一个位置为基准位置 if(i { while(i { while(i if(i while(i if(i } arr[i]=temp;//将基准元素就位 cout<<"第"<<++x<<"趟排序结果为: "; for(intt=0;t cout< cout< quicksort(low,i-1);//在左子区间递归进行快速排序 quicksort(i+1,high);//在右子区间递归进行快速排序 } } g堆排序 (1)建立最大堆的伪代码如下: template voidsortlist : filterdown(constintstart) {//向下调整使从start开始到currentsize-1为止的子表成为最大堆 inti=start,j=2*i+1;//j为i的左孩子 inttablesize=currentsize; typetemp=arr[i]; while(j<=currentsize-1) { if(j j++;//在两个孩子中选关键字较大者 if(temp>=arr[j])break; else{arr[i]=arr[j];i=j;j=2*j+1; } } arr[i]=temp; } (2)堆排序 template voidsortlist : heapsort() { inttablesize=currentsize; for(inti=(currentsize-2)/2;i>=0;i--) filterdown(i);//初始建堆 for(inti=currentsize-1;i>=1;i--) { swap(arr[0],arr[i]);//堆顶元素和最后一个元素交换 currentsize--; filterdown(0);//重建最大堆 cout<<"第"<<++num<<"趟排序结果为: "; for(intt=0;t cout< cout< } num=0; currentsize=tablesize; } h归并排序 归并算法: template voidsortlist : merge(sortlist { inti=left,j=mid+1,k=left;//指针初始化 //i是前一段的当前元素位置,j是后一段的当前元素位置,k是辅助数组的当前位置 while(i<=mid&&j<=right) if(sourcetable.arr[i]<=sourcetable.arr[j]) {mergedtable.arr[k]=sourcetable.arr[i];i++;k++;} else{mergedtable.arr[k]=sourcetable.arr[j];j++;k++;} if(i<=mid) for(intp=k,q=i;q<=mid;p++,q++) mergedtable.arr[p]=sourcetable.arr[q];//把前一段复制到mergedtable else for(intp=k,q=j;q<=right;p++,q++) mergedtable.arr[p]=sourcetable.arr[q];//把后一段复制到mergedtable } 一趟归并算法 template template voidsortlist : mergepass(sortlist { inti=0; while(i+2*len<=currentsize-1)//表示至少有个子序列 { merge(sourcetable,mergedtable,i,i+len-1,i+2*len-1); i+=2*len; } if(i+len<=currentsize-1)//若只有最后两个子序列 merge(sourcetable,mergedtable,i,i+len-1,currentsize-1); else//若只有最后一个子序列 for(intj=i;j<=currentsize-1;j++) mergedtable.arr[j]=sourcetable.arr[j]; if(len<=currentsize-1) { if(num { cout<<"第"<<++num<<"趟排序结果为: "; for(intt=0;t cout< cout< } } } 归并排序: template voidsortlist : mergesort(sortlist {//按数据元素关键字非递减的顺序对排序表table中数据元素进行递归排序 sortlist intlen=1; while(len { mergepass(table,temptable,len);len*=2; mergepass(temptable,table,len);len*=2; } num=0; } i主函数 intmain()//主函数 {intc=1; charch,cc; intn1=0; while(c! =0) { cout<<"███████████████请选择排序的方法███████████████"< cout<<"1直接插入排序2折半插入排序"< cout<<"3冒泡排序4简单选择排序"< cout<<"5快速排序6堆排序"< cout<<"7归并排序0退出排序程序"< cout<<"██████████████████████████████████████"< cout<<"\n请输入您需要的排序种类(键入对应的代号): "; cin>>ch; if(ch=='0'){cout<<"您已成功退出该系统! "< if(ch>='0'&&ch<='7') {cout<<"\n请输入所需排序的个数: "; cin>>n; cout<<"\n请输入"< "; sortlist for(inti=0;i {cin>>number;table.insert(i,number);} switch(ch) { case'1': cout<<"\n███████您选择的是直接插入排序███████\n"< table.insertionsort(); break; system("pause"); break; case'2': cout<<"\n███████您选择的是折半插入排序███████\n"< table.binaryinsertsort(); break; system("pause"); break; case'3': cout<<"\n███████您选择的是冒泡排序███████\n"< table.bubblesort(); break; system("pause"); break; case'4': cout<<"\n███████您选择的是简单选择排序███████\n"< table.selectsort(); break; system("pause"); break; case'5': cout<<"\n███████您选择的是快速排序███████\n"< table.quicksort(0,n-1); break; system("pause"); break; case'6': cout<<"\n███████您选择的是堆排序███████\n"< table.heapsort(); break; system("pause"); break; case'7': cout<<"\n███████您选择的是归并排序███████\n"< table.mergesort(table); break; system("pause"); break; } } } system("pause"); return0; } 三、上机结果及体会: a.程序的性能分析,时空分析: 直接插入排序(稳定的排序方法) 1时间复杂度 a)若待排序记录按关键字从小到大排列(正序) 关键字比较次数: 记录移动次数: 2(n-1) b)若待排序记录按关键字从大到小排列(逆序) 关键字比较次数: 记录移动次数: c)若待排序记录是随机的,取最好和最坏情况的平均值 关键字比较次数(约为): 记录移动次数(约为): 2空间复杂度: S(n)=O (1) b.折半插入排序(稳定的排序算法) 就平均性能而言,因为折半查找优于顺序查找,所以折半插入排序也优于直接插入排序。 关键字的比较次数为: n*log2(n) c.冒泡排序(稳定的排序算法) 1.时间复杂度: a)最好情况(正序) b)比较次数: n-1(只要进行一趟即可) c)移动次数: 0 d)最坏情况(逆序) e)比较次数: (需n-1趟,每趟达到最大比较次数) f)移动次数: 在最坏情况下,时间复杂度为: T(n)=O(n²) 2.空间复杂度: S(n)=O (1) d.简单选择排序(不稳定的排序方法) 1.时间复杂度: O(n2)。 2.空间复杂度: S (1)。 e.快速排序(不稳定的排序方法) 1.时间复杂度 最好情况(每次总是选到中间值作枢轴)T(n)=O(nlog2n) 最坏情况(每次总是选到最小或最大元素作枢轴)T(n)=O(n²) 2.空间复杂度: 需栈空间以实现递归 最坏情况: S(n)=O(n) 一般情况: S(n)=O(log2n) f.堆排序(不稳定的排序方法)] 1.间复杂性为O(nlog2n)。 2空间复杂性为O (1)。 g.归并排序(稳定的排序方法) 1时间复杂度为O(nlog2n)。 2空间复杂度为O(n)。 1、程序运行时的初值和运行结果, 主菜单: 直接插入排序: 折半插入排序: 冒泡排序: 简单选择排序: 快速排序: 堆排序: 归并排序: 退出排序: 2、收获和体会: 在进行为期一个星期的课程设计中,最终完成了算法。 这期间,遇到的各种麻烦也都相继解决。 从这次实践中,我意识到自己还有很多不足之处。 首先先说一下基本的。 对于各种排序算法的过程还是不够熟悉,进行编程时还需要翻书查找,对于这一点,只能说对数据结构的学习还不够扎实,还需要在以后的学习中多多注意C++语言的学习和数据结构的相关知识。 其次,就是对于错误的处理,不能得心应手,不能正确处理一些简单的错误。 对于逻辑上的错误,不能够立即找到出错点,往往需要向同学请教才能找出错误,并且改正。 从总体上说,整个代码的实现还是存在不足的,例如本程序不能判断字符数大于1的字符串,没有相应排序的性能分析(如空间复杂度,时间复杂度),等等。 从这点看,说明自己的程序还是不够完善,不能做到十全十美,希望以后能有所修正。 总而言之,从这次的实践中我学到了很多东西,在以后的学习生活中要多多注意整顿自己的学风,严谨踏实的面对学习之中的问题。 3、源程序代码: #include"stdafx.h" #include usingnamespacestd; constintmaxsize=100; intnum=0;//定义全局变量,为每一趟的输出做准备 intx=0; template
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程 报告 各种 排序 算法 比较