1、课程设计摘要 排序算法是数据结构这门课程核心内容之一,它是计算机程序设计、数据库、操作系统、编译原理级人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。学习排序算法是为了将实际问题中涉及的对象在计算机中对它们进处理。我们将利用vc+6.0开发程序对各种算法进行测试。该测试系统可以通过操作吧数据结构中的主要排序常见的排序算法(直接插入排序、希尔排序、直接选择排序、冒泡排序、快速排序、堆排序、归并排序)的性能用时间的长短表现出来。【关键字】: 数据结构 vc+6.0 排序算法 时间长短一、任务描述使用简单数组实现下面各种排序算法,并进行比较。1、插入排序2、希尔排序3、冒泡排序4、快速
2、排序5、简单选择排序1.要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。 3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。二、 程序分析图2-1 程序分析(1)设计一个菜单,格式如下: 1、直接插入排序 2、希尔排序 3、冒泡排序 4、快速排序 5、选择排序 6、堆排序 7、退出(2)选择不同的菜单但进行相应的排序,并给出排序的关键字序列。三、存储结构关键算法分析本程序包含
3、了9个函数,它们分别是:1.直接插入排序的算法函数InsertSort()。 void InsertSort(SqList &L)int i,j;for( i=2; i=L.length;i+)if(L.ri.key L.ri-1.key)L.r0 = L.ri;L.ri = L.ri-1;for( j=i-2; (L.r0.key L.rj.key); j-) L.rj+1 = L.rj;L.rj+1 = L.r0;2.希尔排序的算法函数ShellSort()。void ShellSort(SqList &L)int i, j;int dk = 1;/增量while(dk 0)dk /= 3
4、;/减小增量for (i = dk; i = dk) & (L.rj-dk.key L.r0.key) L.rj.key = L.rj-dk.key;j -= dk;L.rj.key = L.r0.key;3.冒泡排序算法函数BubbleSort()。void BubbleSort(SqList &L)int i,j;for(i=0;iL.length-2;i+)int flag = 1;for(j=0;j L.rj+1.key)flag = 0;int temp;temp = L.rj.key;L.rj.key = L.rj+1.key;L.rj+1.key = temp;/若无交换说明已经
5、有序if(flag=1)break; 4.快速排序的算法函数Partition()。void BubbleSort(SqList &L)int i,j;for(i=0;iL.length-2;i+)int flag = 1;for(j=0;j L.rj+1.key)flag = 0;int temp;temp = L.rj.key;L.rj.key = L.rj+1.key;L.rj+1.key = temp;/若无交换说明已经有序if(flag=1)break; 5.选择排序算法函数SelectSort()。void SelectSort(SqList &L)int min;int j;fo
6、r (int i = 0; i L.length; i+) / 选择第i小的记录,并交换j = i;min = L.ri.key;for (int k = i; k L.length; k+) / 在Ri.n-1中选择最小的记录if (L.rk.key min)min = L.rk.key ;j = k;if (i != j) / 与第i个记录交换int temp = L.ri.key;L.ri.key = L.rj.key;L.rj.key = temp;6.堆排序算法函数HeapAdjust()。 void HeapAdjust(HeapType &H,int s,int m)/堆调整,将
7、记录调整为小顶堆 int j;RedType rc = H.rs;/暂时存储根结点for(j=2*s; j=m; j*=2)/沿着结点记录较小的向下筛选if(jm & H.rj.key= H.rj.key)break;H.rs = H.rj;s = j;H.rs = rc;void HeapSort(HeapType &H)int i;RedType temp;for(i = H.length; i0; -i)HeapAdjust(H,i,H.length);for(i=H.length; i1; -i)temp = H.r1;H.r1 = H.ri;H.ri = temp;HeapAdjus
8、t(H,1,i-1);7.对存储数字的遍历函数void Visit(SqList L)for(int i=1; i=L.length; i+)coutL.ri.key ;coutendl;void InitSqList(SqList &L,int a)for(int i=1;i=L.length;i+)L.ri.key = ai;8.主函数main()。关键算法的时间、空间复杂度:排序法 平均时间 最差情形 稳定度 额外空间 备注冒泡 O(n2)O(n2) 稳定 O(1) n小时较好交换 O(n2)O(n2) 不稳定 O(1) n小时较好选择 O(n2)O(n2) 不稳定 O(1) n小时较好
9、插入 O(n2) O(n2) 稳定 O(1) 大部分已排序时较好Shell O(nlogn) O(ns) 1s2 不稳定 O(1) s是所选分组快速 O(nlogn)O(n2) 不稳定 O(nlogn) n大时较好归并O(nlogn) O(nlogn) 稳定 O(1) n大时较好堆 O(nlogn) O(nlogn) 不稳定 O(1) n大时较好 四、主函数流程: 图4-1 主函数流程五、程序运行结果1.正序输入图5-1 正序输入2.反序输入图5-2 反序输入3.随机输入图5-3 随机输入参考文献1 数据结构(C语言版) 高等教育出版社 胡学纲编著2 数据结构与算法 高等教育出版社 许卓群、杨
10、东青编著3 新编考研辅导丛书 数据结构辅导 西安电子科技大学出版社 王卫东编著4 数据结构 人民邮电出版社 刘遵仁编著5 数据结构(C语言版)导教、导学、导考 西北工业大学出版社 姚群、夏清国编著6 数据结构(C语言描述) 清华大学出版社 徐孝凯、贺桂英编著7 数据结构(C语言描述)学习指导与习题解析 清华大学出版社 徐孝凯、贺桂英编著8 数据结构(含实训) 东南大学出版社 齐景嘉编著9 数据结构 红旗出版社 张曼、朱小谷等编著10 数据结构习题解析 清华大学出版社 李春葆编著11 数据结构常见题型解析与模拟题 西北工业大学出版社 朱儒荣、朱辉编著12 数据结构习题集与解题指导 科学技术文献出
11、版社 薛晓燕、王晓冬编著13 数据结构(C语言描述) 清华大学出版社 徐孝凯、贺桂英编著附 录(程序清单)#include#include #include using namespace std;int i,j,temp,k;/设置全局变量long double GetNowTime() /取系统时间 LARGE_INTEGER litmp; LONG64 QPart; QueryPerformanceCounter(&litmp); QPart=litmp.QuadPart; return (long double)QPart;/插入排序void InsertSort(int r, int
12、 n) int move=0, compare=0; long double start=0,end=0,time=0; start=GetNowTime(); for(i=2;in;i+) if(riri-1) /记录后项小于记录前项时进行排序 compare+; r0=ri; /设置哨兵,存放待排序记录值 for(j=i-1;r0rj;j-,compare+) /寻找插入位置 rj+1=rj; /比r0大的往后移 rj+1=r0; /插入指定记录值 move=move+3; /关键码的交换按3次记 compare+; end=GetNowTime(); time=end-start; fo
13、r(k=1;kn;k+) coutrk ; /输出排序后记录 coutendl; cout排序所需时间:timeus 移动次数:move 比较次数:compare; coutendl=1;d=d/2) /以增量为d进行直接插入排序 for(i=d+1;i0&r0rj;j=j-d,compare+) rj+d=rj; /记录后移d个位置 rj+d=r0; /插入指定记录值 move=move+3; compare+; end=GetNowTime(); time=end-start; for(i=1;in;i+) coutri ; /输出排序后记录 coutendl; cout排序所需时间:ti
14、meus 移动次数:move 比较次数:compare; coutendlendl;/改进型起泡排序void BubbleSort(int r, int n) long double start=0,end=0,time=0; int move=0,compare=0; int exchange; int bound; exchange=n-1; /第一趟起泡排序的范围是r0到rn-1 start=GetNowTime(); while (exchange) /仅当上一趟排序有记录交换才进行本趟排序 bound=exchange; /表示无序的范围 exchange=0; for(int j=
15、0;jrj+1) temp=rj; /交换ri和ri+1 rj=rj+1; rj+1=temp; move=move+3; exchange=j; /记录每一次发生记录交换的位置,即记录无序区的位置 compare+; end=GetNowTime(); time=end-start; for(int i=0;in;i+) coutri ; /输出排序后记录 coutendl; cout排序所需时间:time us 移动次数:move 比较次数:compare; coutendlendl;/快速排序一次划分int Emove=0,Ecompare=0;long double Etime;int
16、 Partition(int r, int first, int end) i=first; /初始化 j=end; while (ij) /循环的停止条件是i=j while(ij&ri=rj) Ecompare+;j-; /右侧扫描 Ecompare+; if(ij) temp=ri; /将较小记录交换到前面 ri=rj; rj=temp; Emove=Emove+3; /*i+; */ while(ij&ri=rj) Ecompare+; i+; /左侧扫描,小于轴值的不移动,找到大于轴值的 Ecompare+; if(ij) temp=rj; rj=ri; ri=temp; /将较大记
17、录交换到后面 Emove=Emove+3; /* j-;*/ return i; /i为轴值记录的最终位置/快速排序,在一次排序结束后,左边区的元素都比右边区的小,只要分开再排序即可void QuickSort(int r,int first,int end2) long double start=0,end=0; start=GetNowTime(); if (firstend2) /递归结束 int pivot=Partition(r,first,end2); /一次划分 QuickSort(r,first,pivot-1); /递归地对左侧子序列进行快速排序 QuickSort(r,pi
18、vot+1,end2); /递归地对右侧子序列进行快速排序 end=GetNowTime(); Etime=end-start;void Print() coutendl排序所需时间:Etimeus;移动的次数:Emove;比较的次数:Ecompareendlendl;/简单选择排序,每一趟都找到最小值与比较域内第一个值交换void SelectSort(int r, int n) long double start=0,end=0,time=0; int compare=0,move=0; int index; /设置关键值下标 start=GetNowTime(); for(i=0;in-
19、1;i+) /对n个记录进行n-1趟简单选择排序 index=i; for(j=i+1;jn;j+,compare+) /在无序区中选取最小记录 if(rjrindex) /有记录小于关键值记录 index=j; /更新关键值记录 if(index!=i) /若第一个是最小值就不用交换 temp=ri; ri=rindex; rindex=temp; /交换ri和关键值记录 move=move+3; compare+; end=GetNowTime(); time=end-start; for(i=0;in;i+) coutri ; /输出排序后记录 coutendl排序所需时间:timeus
20、 移动次数:move 比较次数:compare; coutendlendl;/对数列进行排序void px(int r,int numv) coutn直接顺序排序结果为: ; InsertSort(r,numv); cout希尔排序结果为: ; ShellSort(r,numv); cout起泡排序结果为: ; BubbleSort(r, numv-1); cout快速排序结果为: ; QuickSort(r,0,numv-1); for(int i=0;inumv-1;i+) coutri ; Print(); Emove=0;Ecompare=0; coutn; cout简单选择排序结果为
21、: ; SelectSort(r,numv-1);/主函数int main() const int numv=11; int anumv=0; int bnumv=0; int cnumv=0; /初始化 cout请输入10位正整数.endl; cout第一组,正序输入 a= ; try for(i=1;iai; /从键盘输入待排序记录值 catch(char *wrong) coutwrong; px(a,numv); /调用排序函数 coutn第二组,反序输入 b= ; try for(i=1;ibi; /从键盘输入待排序记录值 catch(char *wrong) coutwrong;
22、px(b,numv); /调用排序函数 coutn第三组,随机输入 c= ; try for(i=1;ici; /从键盘输入待排序记录值 catch(char *wrong) coutwrong; px(c,numv); /调用排序函数 return 0;在初期构思代码的时候,首先构造了各种算法的基本实现代码,封装成类,已经能够实现七种排序的基本功能,并且测试无误。后来考虑能否优化本程序,首先考虑到测试算法的需求,需要大量随机数,因为增添了随机函数发生器,满足各种测试条件的需求。之后考虑如何能简化代码以实现多达七种排序算法的简单调用、乱序和顺序以及逆序数据的分别排序和性能指标统计、算法时间的精
23、确而简易的统计、算法移动次数和比较次数的精确统计。如果设计不合理,将使得主调函数的调用代码冗长,可读性变差。因而采用了函数指针数组和统一的接口函数,采用二维数组存储移动次数和比较次数,调用精确的系统函数实现时间的统计。此外还添加了一些列优化,特别是函数封装的方法,使得程序的结构变得更加合理,版面风格也变得好看,可读性增强。程序的优化是一个艰辛的过程,如果只是实现一般的功能,将变得容易很多,当加上优化,不论是效率还是结构优化,都需要精心设计。这次做优化的过程中,遇到不少阻力。由于优化中用到很多类的封装和访问控制方面的知识,而这部分知识恰好是大一一年学习的薄弱点。因而以后要多花力气学习C+编程语言,必须要加强这方面的训练,这样才能在将编程思想和数据结构转换为代码的时候能得心应手。改进:本程序代码设计时运用了递归的调用方式,效率还可以通过将其转换为栈模拟的方式得以提高。在实现类的封装的时候为了共享数据采用了友元函数的方式,考虑能否使用其他方式使得类的封装更加完善。指导教师评语:指导教师(签字): 年 月 日
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1