北邮数据结构实验报告-排序
- 格式:doc
- 大小:208.50 KB
- 文档页数:15
北京邮电大学数据结构试验报告实验名称:实验四排序学生姓名:班级:班内序号:学号:日期:2014年1月4日1 实验目的学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
2 实验内容2.1 题目1使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。
3 程序分析3.1 存储结构顺序存储结构——数组3.2 关键算法分析1.插入排序:依次将待排序的序列中的每一个记录插入到先前排序好的序列中,直到全部记录排序完毕void Insertsort(int r[],int n,int* compare,int* move)//插入排序{*compare=0;*move=0;int i;int j;for(i=1;i<n;i++)//一共要排序n-1次{int x=r[i];for(j=i-1;x<r[j]&&j>=0;j--){(*compare)++;(*move)++;r[j+1]=r[j];}if(j>=0) (*compare)++;r[j+1]=x;}}2.希尔排序:先将整个序列分割成若干个子列,分别在各个子列中运用直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序void ShellInsert(int r[],int n,int* compare,int* move)//希尔排序{*compare=0;*move=0;int j;10 9 12 12 20 20 31for(int d=n/2;d>=1;d=d/2)//间距越来越小{for(int i=d;i<=n-1;i++)//从a[d]往后逐个元素确定是否需要前移{if(r[i]<r[i-d])//某元素比同组中的前一位小,则需要前移{int x=r[i];for(j=i-d;(j>=0)&&(x<r[j]);j=j-d)//完成所需的所有前移{(*compare)++;(*move)++;r[j+d]=r[j];}if(j>=0) (*compare)++;r[j+d]=x;}else (*compare)++;}}}3.冒泡排序:两两比较相邻记录的关键码,如果反序则交换,直到没有反序记录为止void Bubblesort(int r[],int n,int* compare,int* move)//交换(冒泡)排序{*compare=0;*move=0;int x;for(int j=0;j<n-1;j++)//冒泡排序n-1次{for(int i=n-1;i>j;i--){if(r[i]<r[i-1]){(*compare)++;(*move)+=3;x=r[i];r[i]=r[i-1];r[i-1]=x;}else (*compare)++;}}}4.快速排序:首先选择一个基准,将记录分割为两部分,左支小于或等于基准,右支则大于基准,然后对两部分重复上述过程,直至整个序列排序完成int Partion(int r[],int first,int end,int* compare,int* move)//快速排序中的轴定位{int i=first;int j=end;int zhou=r[i];//默认第一个元素为轴while(i<j){while((i<j)&&(r[j]>=zhou)) //查看右侧元素与轴的大小关系{(*compare)++;j--;}if(i<j){(*compare)++;(*move)++;r[i]=r[j];//发现轴右侧的某数比轴值小,将其前置}while((i<j)&&(r[i]<=zhou))//查看左侧元素与轴的大小关系{(*compare)++;i++;}if(i<j){(*compare)++;(*move)++;r[j]=r[i];//发现轴左侧的某数比轴值小,将其后置}}r[i]=zhou;//最后确定轴的位置return i;}void Qsort(int r[],int i,int j,int* compare,int* move)//快速排序{if(i<j){int centre=Partion(r,i,j,compare,move);Qsort(r,i,centre-1,compare,move);Qsort(r,centre+1,j,compare,move);}}5.选择排序:从待排序的记录序列中选择关键码最小的记录并将它与序列中的第一个记录交换位置;然后从不包括第一个位置上的记录序列中选择关键码最小(或最大)的记录并将它与序列中的第二个记录交换位置;如此重复,直到序列中只剩下一个记录为止void Selectsort(int r[],int n,int* compare,int* move)//选择排序{*compare=0;*move=0;for(int i=0;i<n-1;i++)//排序n-1次{int min=i;for(int j=i+1;j<n;j++)//通过此层循环,找到真正的第i个最小值{(*compare)++;if(r[j]<r[min]) min=j;//记录下当前找到的最小值的位置}if(min!=i){(*move)+=3;int Min;Min=r[min];r[min]=r[i];r[i]=Min;}}}4 程序运行结果4.1主函数流程图4.2程序运行框图5 实验心得1.调试时出现的问题及解决的方法在初期构思代码的时候,首先构造了各种算法的基本实现代码,封装成类,已经能够实现七种排序的基本功能,并且测试无误。
之后考虑如何能简化代码以实现多达七种排序算法的简单调用、乱序和顺序以及逆序数据的分别排序和性能指标统计(算法移动次数和比较次数的精确统计)。
2.心得体会程序的优化是一个艰辛的过程,如果只是实现一般的功能,将变得容易很多,当加上优化,不论是效率还是结构优化,都需要精心设计。
3.改进本程序代码设计时运用了递归的调用方式,效率还可以通过将其转换为栈模拟的方式得以提高。
另外还可以进一步考虑算法时间的精确统计,以便从时间角度比较这几种排序算法的优劣。
完整源代码#include<iostream>using namespace std;void Insertsort(int r[],int n,int* compare,int* move);void ShellInsert(int r[],int n,int* compare,int* move);void Bubblesort(int r[],int n,int* compare,int* move);int Partion(int r[],int first,int end,int* compare,int* move);void Qsort(int r[],int i,int j,int* compare,int* move);void Selectsort(int r[],int n,int* compare,int* move);void Insertsort(int r[],int n,int* compare,int* move)//插入排序{*compare=0;*move=0;int i;int j;for(i=1;i<n;i++)//一共要排序n-1次{int x=r[i];for(j=i-1;x<r[j]&&j>=0;j--){(*compare)++;(*move)++;r[j+1]=r[j];}if(j>=0) (*compare)++;r[j+1]=x;}}void ShellInsert(int r[],int n,int* compare,int* move)//希尔排序{*compare=0;*move=0;int j;for(int d=n/2;d>=1;d=d/2)//间距越来越小{for(int i=d;i<=n-1;i++)//从a[d]往后逐个元素确定是否需要前移{if(r[i]<r[i-d])//某元素比同组中的前一位小,则需要前移{int x=r[i];for(j=i-d;(j>=0)&&(x<r[j]);j=j-d)//完成所需的所有前移{(*compare)++;(*move)++;r[j+d]=r[j];}if(j>=0) (*compare)++;r[j+d]=x;}else (*compare)++;}}}void Bubblesort(int r[],int n,int* compare,int* move)//交换(冒泡)排序{*compare=0;*move=0;int x;for(int j=0;j<n-1;j++)//冒泡排序n-1次{for(int i=n-1;i>j;i--){if(r[i]<r[i-1]){(*compare)++;(*move)+=3;x=r[i];r[i]=r[i-1];r[i-1]=x;}else (*compare)++;}}int Partion(int r[],int first,int end,int* compare,int* move)//快速排序中的轴定位{int i=first;int j=end;int zhou=r[i];//默认第一个元素为轴while(i<j){while((i<j)&&(r[j]>=zhou)) //查看右侧元素与轴的大小关系{(*compare)++;j--;}if(i<j){(*compare)++;(*move)++;r[i]=r[j];//发现轴右侧的某数比轴值小,将其前置}while((i<j)&&(r[i]<=zhou))//查看左侧元素与轴的大小关系{(*compare)++;i++;}if(i<j){(*compare)++;(*move)++;r[j]=r[i];//发现轴左侧的某数比轴值小,将其后置}}r[i]=zhou;//最后确定轴的位置return i;}void Qsort(int r[],int i,int j,int* compare,int* move)//快速排序{if(i<j){int centre=Partion(r,i,j,compare,move);Qsort(r,i,centre-1,compare,move);Qsort(r,centre+1,j,compare,move);}void Selectsort(int r[],int n,int* compare,int* move)//选择排序{*compare=0;*move=0;for(int i=0;i<n-1;i++)//排序n-1次{int min=i;for(int j=i+1;j<n;j++)//通过此层循环,找到真正的第i个最小值{(*compare)++;if(r[j]<r[min]) min=j;//记录下当前找到的最小值的位置}if(min!=i){(*move)+=3;int Min;Min=r[min];r[min]=r[i];r[i]=Min;}}}void main(){int i;int compare=0;int move=0;cout<<"请您先输入一个正序数组哦"<<endl;int n;cout<<"请输入数组中含有的元素数量:";cin>>n;int *r=new int[n];cout<<"请输入数组中的元素:";for(i=0;i<n;i++) cin>>r[i];int *a=new int[n];for(i=0;i<n;i++) {a[i]=r[i];}Insertsort(a,n,&compare,&move);cout<<"\n插入排序结果为:";for(i=0;i<n;i++) cout<<a[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl;int *b=new int[n];for(i=0;i<n;i++) {b[i]=r[i];}ShellInsert(b,n,&compare,&move);cout<<"希尔排序结果为:";for(i=0;i<n;i++) cout<<b[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; int *c=new int[n];for(i=0;i<n;i++) {c[i]=r[i];}Bubblesort(c,n,&compare,&move);cout<<"交换排序结果为:";for(i=0;i<n;i++) cout<<c[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; compare=0;move=0;int *d=new int[n];for(i=0;i<n;i++) {d[i]=r[i];}Qsort(d,0,n-1,&compare,&move);cout<<"快速排序结果为:";for(i=0;i<n;i++) cout<<d[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; int *e=new int[n];for(i=0;i<n;i++) {e[i]=r[i];}Selectsort(e,n,&compare,&move);cout<<"选择排序结果为:";for(i=0;i<n;i++) cout<<e[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl;cout<<"再输入一个逆序数组~~~"<<endl; cout<<"请输入数组中含有的元素数量:"; cin>>n;cout<<"请输入数组中的元素:";for(i=0;i<n;i++) cin>>r[i];for(i=0;i<n;i++) {a[i]=r[i];}Insertsort(a,n,&compare,&move);cout<<"\n插入排序结果为:";for(i=0;i<n;i++) cout<<a[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; for(i=0;i<n;i++) {b[i]=r[i];}ShellInsert(b,n,&compare,&move);for(i=0;i<n;i++) cout<<b[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; for(i=0;i<n;i++) {c[i]=r[i];}Bubblesort(c,n,&compare,&move);cout<<"交换排序结果为:";for(i=0;i<n;i++) cout<<c[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; compare=0;move=0;for(i=0;i<n;i++) {d[i]=r[i];}Qsort(d,0,n-1,&compare,&move);cout<<"快速排序结果为:";for(i=0;i<n;i++) cout<<d[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; for(i=0;i<n;i++) {e[i]=r[i];}Selectsort(e,n,&compare,&move);cout<<"选择排序结果为:";for(i=0;i<n;i++) cout<<e[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl;cout<<"最后输入一个乱序数组~~~"<<endl; cout<<"请输入数组中含有的元素数量:"; cin>>n;cout<<"请输入数组中的元素:";for(i=0;i<n;i++) cin>>r[i];for(i=0;i<n;i++) {a[i]=r[i];}Insertsort(a,n,&compare,&move);cout<<"\n插入排序结果为:";for(i=0;i<n;i++) cout<<a[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; for(i=0;i<n;i++) {b[i]=r[i];}ShellInsert(b,n,&compare,&move);cout<<"希尔排序结果为:";for(i=0;i<n;i++) cout<<b[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; for(i=0;i<n;i++) {c[i]=r[i];}Bubblesort(c,n,&compare,&move);for(i=0;i<n;i++) cout<<c[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; compare=0;move=0;for(i=0;i<n;i++) {d[i]=r[i];}Qsort(d,0,n-1,&compare,&move);cout<<"快速排序结果为:";for(i=0;i<n;i++) cout<<d[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; for(i=0;i<n;i++) {e[i]=r[i];}Selectsort(e,n,&compare,&move);cout<<"选择排序结果为:";for(i=0;i<n;i++) cout<<e[i]<<' ';cout<<"\n比较次数为"<<compare;cout<<"\n移动次数为"<<move<<'\n'<<endl; }。