南邮数据结构上机实验四内排序算法的实现以及性能比较

合集下载

南邮数据结构上机实验四内排序算法的实现以及性能比较介绍

南邮数据结构上机实验四内排序算法的实现以及性能比较介绍

实验报告(2015 / 2016学年第二学期)课程名称数据结构A实验名称内排序算法的实现以及性能比较实验时间2016 年 5 月26 日指导单位计算机科学与技术系指导教师骆健学生姓名耿宙班级学号B14111615学院(系) 管理学院专业信息管理与信息系统实习题名:内排序算法的实现及性能比较班级 B141116 姓名耿宙学号 B14111615 日期2016.05.26 一、问题描述验证教材的各种内排序算法,分析各种排序算法的时间复杂度;改进教材中的快速排序算法,使得当子集合小于10个元素师改用直接插入排序;使用随即数发生器产生大数据集合,运行上述各排序算法,使用系统时钟测量各算法所需的实际时间,并进行比较。

系统时钟包含在头文件“time.h”中。

二、概要设计文件Sort.cpp中包括了简单选择排序SelectSort(),直接插入排序InsertSort(),冒泡排序BubbleSort(),两路合并排序Merge(),快速排序QuickSort()以及改进的快速排序GQuickSort()六个内排序算法函数。

主主函数main的代码如下图所示:三、详细设计1.类和类的层次设计在此次程序的设计中没有进行类的定义。

程序的主要设计是使用各种内排序算法对随机生成的数列进行排列,并进行性能的比较,除此之外还对快速排序进行了改进。

下图为主函数main的流程图:main()2.核心算法1)简单选择排序:简单选择排序的基本思想是:第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。

2)直接插入排序:插入排序的思想是将一组无序的元素分别插入一个已经有序的的数组里,并保证插入后的数组也是有序的。

当所有无序组的元素都插入完毕时,一个有序数组构造完成。

(完整)数据结构(C语言版)实验报告 (内部排序算法比较)

(完整)数据结构(C语言版)实验报告 (内部排序算法比较)

(完整)数据结构(C语言版)实验报告 (内部排序算法比较)编辑整理:尊敬的读者朋友们:这里是精品文档编辑中心,本文档内容是由我和我的同事精心编辑整理后发布的,发布之前我们对文中内容进行仔细校对,但是难免会有疏漏的地方,但是任然希望((完整)数据结构(C语言版)实验报告 (内部排序算法比较))的内容能够给您的工作和学习带来便利。

同时也真诚的希望收到您的建议和反馈,这将是我们进步的源泉,前进的动力。

本文可编辑可修改,如果觉得对您有帮助请收藏以便随时查阅,最后祝您生活愉快业绩进步,以下为(完整)数据结构(C语言版)实验报告 (内部排序算法比较)的全部内容。

《数据结构与算法》实验报告一、需求分析问题描述:在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。

试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受.基本要求:(l)对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

(2)待排序表的表长不小于100000;其中的数据要用伪随机数程序产生;至少要用5组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)。

(3)最后要对结果作简单分析,包括对各组数据得出结果波动大小的解释。

数据测试:二.概要设计1.程序所需的抽象数据类型的定义:typedef int BOOL; //说明BOOL是int的别名typedef struct StudentData { int num; //存放关键字}Data; typedef struct LinkList { int Length; //数组长度Data Record[MAXSIZE]; //用数组存放所有的随机数} LinkList int RandArray[MAXSIZE]; //定义长度为MAXSIZE的随机数组void RandomNum() //随机生成函数void InitLinkList(LinkList* L) //初始化链表BOOL LT(int i, int j,int* CmpNum) //比较i和j 的大小void Display(LinkList* L) //显示输出函数void ShellSort(LinkList* L, int dlta[], int t,int* CmpNum, int* ChgNum) //希尔排序void QuickSort (LinkList*L,int* CmpNum, int*ChgNum) //快速排序void HeapSort (LinkList* L, int* CmpNum, int*ChgNum) //堆排序void BubbleSort(LinkList*L,int* CmpNum, int*ChgNum) //冒泡排序void SelSort(LinkList* L, int* CmpNum,int*ChgNum)//选择排序void Compare(LinkList* L,int*CmpNum,int* ChgNum) //比较所有排序2 .各程序模块之间的层次(调用)关系:二、详细设计typedef int BOOL; //定义标识符关键字BOOL别名为int typedef struct StudentData //记录数据类型{int num; //定义关键字类型}Data; //排序的记录数据类型定义typedef struct LinkList //记录线性表{int Length; //定义表长Data Record[MAXSIZE]; //表长记录最大值}LinkList; //排序的记录线性表类型定义int RandArray[MAXSIZE]; //定义随机数组类型及最大值/******************随机生成函数********************/void RandomNum(){int i; srand((int)time(NULL)); //用伪随机数程序产生伪随机数for(i=0; i小于MAXSIZE; i++) RandArray[i]〈=(int)rand();返回;}/*****************初始化链表**********************/void InitLinkList(LinkList* L) //初始化链表{int i;memset(L,0,sizeof(LinkList));RandomNum();for(i=0; i小于〈MAXSIZE; i++)L—〉Record[i]。

数据结构实验四题目一排序实验报告

数据结构实验四题目一排序实验报告

数据结构实验报告实验名称:实验四——排序学生:XX班级:班序号:学号:日期:1.实验要求实验目的:通过选择实验容中的两个题目之一,学习、实现、对比、各种排序的算法,掌握各种排序算法的优劣,以及各种算法使用的情况。

题目1:使用简单数组实现下面各种排序算法,并进行比较。

排序算法如下:1、插入排序;2、希尔排序;3、冒泡排序;4、快速排序;5、简单选择排序;6、堆排序;7、归并排序;8、基数排序(选作);9、其他。

具体要求如下:1、测试数据分成三类:正序、逆序、随机数据。

2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为3次移动)。

3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙。

4、对2和3的结果进行分析,验证上述各种算法的时间复杂度。

5、编写main()函数测试各种排序算法的正确性。

2. 程序分析2.1 存储结构存储结构:数组2.2 关键算法分析一、关键算法:1、插入排序a、取排序的第二个数据与前一个比较b、若比前一个小,则赋值给哨兵c、从后向前比较,将其插入在比其小的元素后d、循环排序2、希尔排序a、将数组分成两份b、将第一份数组的元素与哨兵比较c、若其大与哨兵,其值赋给哨兵d、哨兵与第二份数组元素比较,将较大的值赋给第二份数组e、循环进行数组拆分3、对数据进行编码a、取数组元素与下一个元素比较b、若比下一个元素大,则与其交换c、后移,重复d、改变总元素值,并重复上述代码4、快速排序a、选取标准值b、比较高低指针指向元素,若指针保持前后顺序,且后指针元素大于标准值,后指针前移,重新比较c、否则后面元素赋给前面元素d、若后指针元素小于标准值,前指针后移,重新比较e、否则前面元素赋给后面元素5、简单选择排序a、从数组中选择出最小元素b、若不为当前元素,则交换c、后移将当前元素设为下一个元素6、堆排序a、生成小顶堆b、将堆的根节点移至数组的最后c、去掉已做过根节点的元素继续生成小顶堆d、数组倒置7、归并排序a、将数组每次以1/2拆分,直到为最小单位b、小相邻单位数组比较重排合成新的单位c、循环直至完成排序二、代码详细分析:1、插入排序关键代码:①取排序的第二个数据与前一个比较:if(r[i]<r[i-1])②若比前一个小,则赋值给哨兵:r[0]=r[i];③从后向前比较,将其插入在比其小的元素后:for(j=i-1;r[0]<r[j];j--){r[j+1]=r[j];a++;} r[j+1]=r[0];④循环排序2、希尔排序关键代码:①将数组分成两份:d=n/2②将第一份数组的元素与哨兵比较:for(int i=d+1;i<=n;i++)③若其大与哨兵,其值赋给哨兵:if(r[0]<r[i-d]){ r[0]=r[i];}④哨兵与第二份数组元素比较,将较大的值赋给第二份数组:for(j=i-d;j>0&&r[0]<r[j];j=j-d) {r[j+d]=r[j]; }⑤循环进行数组拆分:for(int;d>=1;d=d/2)3、冒泡排序关键代码:①取数组元素与下一个元素比较: for(int i=1;i<bound;i++)if(r[i]>r[i+1])②若比下一个元素大,则与其交换: r[0]=r[i]; r[i]=r[i+1]; r[i+1]=r[0];③后移,重复:for(int i=1;i<bound;i++)④改变总元素值,并重复上述代码:int bound=pos;4、快速排序关键代码:①选取标准值:r[0]=r[i]②比较高低指针指向元素,若指针保持前后顺序,且后指针元素大于标准值,后指针前移,重新比较:while(i<j&&r[j]>=flag) {j--;}③否则后面元素赋给前面元素:r[i]=r[j];④若后指针元素小于标准值,前指针后移,重新比较:while(i<j&&r[i]<=flag){i++;}⑤否则前面元素赋给后面元素:r[j]=r[i];5、简单选择排序关键代码:①从数组中选择出最小元素: for(int j=i+1;j<=n;j++)②{if(r[j]<r[index]) index=j; }③若不为当前元素,则交换:if(index!=i) {r[0]=r[i]; r[i]=r[index];r[index]=r[0];}④后移将当前元素设为下一个元素:for(int i=1;i<n;i++)6、堆排序关键代码:①生成小顶堆:while(j<=m) {if(j<m&&r[j]>r[j+1]) {j++;}②if(r[i]<r[j]) {break; }③else{ int x; x=r[i]; r[i]=r[j]; r[j]=x; i=j; j=2*i; }}④将堆的根节点移至数组的最后: x=r[1]; r[1]=r[n-i+1]; r[n-i+1]=x;⑤去掉已做过根节点的元素继续生成小顶堆:sift(r,1,n-i,x,y);⑥数组倒置输出: for(int i=n;i>0;i--)cout<<r[i]<<" ";7、归并排序关键代码:①将数组每次以1/2拆分,直到为最小单位: mid=(low+high)/2;②小相邻单位数组比较重排合成新的单位:while(i<=m&&j<=high)if(L.r[i]<=L.r[j]) t[k++]=L.r[i++];else t[k++]=L.r[j++];while(i<=m) t[k++]=L.r[i++];while(j<=high) t[k++]=L.r[j++];for(i=low,k=0;i<=high;i++,k++) L.r[i]=t[k];三、计算关键算法的时间、空间复杂度插入排序O(n2)希尔排序O(n2)冒泡排序O(n2)快速排序O(nlog2n)简单选择排序O(n2)堆排序O(nlog2n)归并排序O(nlog2n)3. 程序运行结果1、测试主函数流程:流程图如图所示流程图示意图程序运行结果图如下:2、测试条件:按题目要求分别输入同组数据的正序、逆序、随机序列进行测试。

排序算法的原理与性能比较

排序算法的原理与性能比较

排序算法的原理与性能比较排序算法是计算机领域中基础的算法之一,它可以对一组数据按照特定的顺序进行排列。

排序算法的性能可以通过其时间复杂度和空间复杂度来衡量,不同的排序算法在不同的数据情况下表现出不同的性能。

常见的排序算法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序等。

冒泡排序是一种简单的排序算法,它重复地比较相邻的两个元素,如果它们的顺序不正确就交换它们,直到整个数组完成排序。

时间复杂度为O(n^2),空间复杂度为O(1)。

选择排序是另一种简单的排序算法,它每次从未排序的数据中选择最小的元素放入已排序部分的末尾。

时间复杂度为O(n^2),空间复杂度为O(1)。

插入排序是将数组分成已排序和未排序两部分,每次从未排序部分取出一个元素插入到已排序部分的正确位置。

时间复杂度为O(n^2),空间复杂度为O(1)。

希尔排序是插入排序的改进版,它通过将整个数组分成若干个子序列进行插入排序,最后再对整个数组进行一次插入排序。

时间复杂度为O(n log n),空间复杂度为O(1)。

归并排序是一种稳定的排序算法,它采用分治的思想将数组分成两半递归地进行排序,最后将两个有序的子数组合并成一个有序的数组。

时间复杂度为O(n log n),空间复杂度为O(n)。

快速排序是一种常用的排序算法,它选择一个基准元素将数组分成两部分,比基准元素小的放在左边,大的放在右边,然后递归地对左右两部分进行排序。

时间复杂度为O(n log n),空间复杂度为O(log n)。

堆排序是一种利用堆的性质进行排序的算法,它首先将数组构建成一个最大堆或最小堆,然后每次将堆顶元素取出放入已排序部分,并调整堆使得剩下的元素仍满足堆的性质。

时间复杂度为O(n log n),空间复杂度为O(1)。

综上所述,不同的排序算法在不同的数据情况下表现出不同的性能,选择合适的排序算法对于提高程序的效率至关重要。

在实际应用中,需要根据数据规模和特点选择合适的排序算法来达到最优的性能。

数据结构 各种内排序性能比较 课程设计报告

数据结构 各种内排序性能比较 课程设计报告

数据结构课程设计报告题目:各种内排序性能比较学生姓名:学号:班级:指导教师:2011-6-13目录1、需求分析说明 (2)1.1所需完成的任务及要求1.2程序实现的功能2、总体设计 (3)2.1 总体设计说明2.2 总体流程图2.3各主程序详细流程图3、详细设计 (7)3.1使用的算法思想3.2各个算法的效率简析4、实现部分 (8)4.1程序算法的代码5、程序测试 (15)5.1程序运行的主界面5.2 各算法运行界面6、总结 (18)1、需求分析说明排序是数据处理中经常遇到的一种重要操作。

然而排序的算法有很多,各有其优缺点和使用场合。

本程序的设计的主要目的是通过比较各种内部排序(包括:插入法排序、起泡法、选择法、快速法、合并法排序)的时间复杂度,即元素比较次数和移动次数,来分析各种算法优缺点和适合排列何种序列。

达到在实际应用中选择合适的方法消耗最短的时间完成排序。

1.1所需完成的任务及要求任务:1)用程序实现插入法排序、起泡法、选择法、快速法、合并法排序;2)输入的数据形式为任何一个正整数,大小不限。

要求:排序后的数组是从小到大的;1.2程序实现的功能(1)使用随机函数实现数组初始化,生成多组元素个数不同的数组;(2)用列表打印出每种排序下的各趟排序结果;(3)打印使用各种排序算法以后元素比较和交换的次数;(4)设计合理的打印列表来打印。

2、总体设计(从总体上说明该题目的框架,用文字和图表说明)2.1 总体设计说明采用插入气泡,选择,快速,合并的方法实现各种排序算法,并且在实现过程中插入适当变量来实现计数元素交换次数和比较次数的统计。

对于每一趟比较之后元素顺序以及最后的结果使用单独的函数来实现,形成单独的一个模块;2.2 总体流程图2.3 各主程序详细流程图①主函数流程图:3、详细设计3.1 使用的算法思想(1)对主界面的menu菜单,在主函数里面用switch语句调用各个模块的功能调用;(2)在插入法时,其算法思想是:将第一个元素作为单独的一个数组独立出来,对剩下的元素,逐个与前面的数组从后往前进行比较,一旦发现当前的元素大于或是等于前面已经排序好的元素中某个元素,则在这个元素之后插入即可;(3)在起泡法时,其算法思想是:将待排序的数组从后往前,依次比较相邻的两个元素,如果发现逆序则交换序列,使得数值、比较小的元素逐渐往前排列,在这个算法时要用flag作为标记位,用来判断元素是否交换,用以减少不必要的交换次数;(4)对于选择法,其排序思想是:从第一个元素开始,并且标记当前元素的位置,比较后面所有的元素,找到其中最小的元素,也标记当前元素的位置,然后把两个标记位的元素进行交换,前面的标记位不断地向后移动,直到最后一个元素的位置,则排序完成;(5)对于快速法,其算法思想是:一般取数组中的第一个元素为基准,通过一趟排序将待排序元素分为左右两个子序列,左子序列的所有元素都小于或等于右子序列的所有元素,然后将左右两个序列按照与此相同的原理进行排序,直至整个序列有序为止,排序完成。

数据结构试验报告——各种内排序算法的实现及性能比较

数据结构试验报告——各种内排序算法的实现及性能比较

实验报告(2010 / 2011 学年第 2 学期)课程名称数据结构——使用C++语言描述实验名称各种内排序算法的实现及性能比较实验时间2011年5月27日指导单位计算机科学与技术系指导教师学生姓名班级学号学院(系)专业一.实验目的和要求内容:验证教材的各种内排序算法。

分析各种排序算法的时间复杂度。

要求:使用随机数产生器产生大数据集合,运行上述各种排序算法,使用系统时钟测量各算法所需的实际时间,并进行比较。

二.实验环境(实验设备)Visual C++三.实验原理及内容单选择排序"<<endl;接插入排序"<<endl;泡排序"<<endl;速排序"<<endl;路合并排序"<<endl;排序"<<endl;出"<<endl;cout<<"PS:测试用的数组元素为"<<SIZE<<"时间为重复运行"<<TIMES<<"次的时间(包括了产生数据与析构的时间)"<<endl;this->switcha();}template <class T>void Menu<T>::childmenu(){cout<<"--------------------------------------------------------"<<endl;cout<<"1.最好情况"<<endl;cout<<"2.最坏情况"<<endl;cout<<"3.平均情况"<<endl;cout<<"4.返回主菜单"<<endl;cin>>b;if(b==4)this->printmenu();}template<class T>void Menu<T>::childmenu2(){cout<<"--------------------------------------------------------"<<endl;cout<<"1.原始算法"<<endl;cout<<"2.改进算法"<<endl;cout<<"3.返回主菜单"<<endl;cin>>c;if(c==3)this->printmenu();}template <class T>void Menu<T>::switcha(){<<endl;return 0;}/*ok--------------------------------------------------------内排序测试系统--------------------------------------------------------1.简单选择排序2.直接插入排序3.冒泡排序4.快速排序5.两路合并排序6.堆排序7.退出PS:测试用的数组元素为400时间为重复运行1000次的时间(包括了产生数据与析构的时间)ok1简单选择排序直接用随机数据测试ok用时:请按任意键继续. . .--------------------------------------------------------内排序测试系统--------------------------------------------------------1.简单选择排序2.直接插入排序3.冒泡排序4.快速排序5.两路合并排序6.堆排序7.退出PS:测试用的数组元素为400时间为重复运行1000次的时间(包括了产生数据与析构的时间)ok2直接插入排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单1ok用时:0请按任意键继续. . .直接插入排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单2ok用时:请按任意键继续. . .直接插入排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单3ok用时:请按任意键继续. . .直接插入排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单4--------------------------------------------------------内排序测试系统--------------------------------------------------------1.简单选择排序2.直接插入排序3.冒泡排序4.快速排序5.两路合并排序6.堆排序7.退出PS:测试用的数组元素为400时间为重复运行1000次的时间(包括了产生数据与析构的时间)ok3冒泡排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单1ok用时:请按任意键继续. . .冒泡排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单2ok用时:请按任意键继续. . .冒泡排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单3ok用时:请按任意键继续. . .冒泡排序--------------------------------------------------------1.最好情况2.最坏情况3.平均情况4.返回主菜单4--------------------------------------------------------内排序测试系统--------------------------------------------------------1.简单选择排序2.直接插入排序3.冒泡排序4.快速排序5.两路合并排序6.堆排序7.退出PS:测试用的数组元素为400时间为重复运行1000次的时间(包括了产生数据与析构的时间)ok4--------------------------------------------------------1.原始算法2.改进算法3.返回主菜单1原始快速排序直接用随机数据测试ok用时:请按任意键继续. . .--------------------------------------------------------1.原始算法2.改进算法3.返回主菜单2改进的快速排序直接用随机数据测试ok用时:请按任意键继续. . .--------------------------------------------------------1.原始算法2.改进算法3.返回主菜单3--------------------------------------------------------内排序测试系统--------------------------------------------------------1.简单选择排序2.直接插入排序3.冒泡排序4.快速排序5.两路合并排序6.堆排序7.退出PS:测试用的数组元素为400时间为重复运行1000次的时间(包括了产生数据与析构的时间)ok5合并排序直接用随机数据测试ok用时:请按任意键继续. . .--------------------------------------------------------内排序测试系统--------------------------------------------------------1.简单选择排序2.直接插入排序3.冒泡排序4.快速排序5.两路合并排序6.堆排序7.退出PS:测试用的数组元素为400时间为重复运行1000次的时间(包括了产生数据与析构的时间)ok6堆排序直接用随机数据测试ok用时:请按任意键继续. . .--------------------------------------------------------内排序测试系统--------------------------------------------------------1.简单选择排序2.直接插入排序3.冒泡排序4.快速排序5.两路合并排序6.堆排序7.退出PS:测试用的数组元素为400时间为重复运行1000次的时间(包括了产生数据与析构的时间)ok7Press any key to continue*/四.实验小结(包括问题解和解决方法、心得体会、意见与建议等)通过本次实验对教材上的各种内排序算法进行了逐一验证。

数据结构之排序算法性能分析比较

数据结构之排序算法性能分析比较

2.1 直接插入排序假设待排序的n个记录{R0,R1,…,Rn}顺序存放在数组中,直接插入法在插入记录Ri(i=1,2,…,n-1)时,记录被划分为两个区间[R0,Ri-1]和[Ri+1,Rn-1],其中,前一个子区间已经排好序,后一个子区间是当前未排序的部分,将关键码Ki与Ki-1Ki-2,…,K0依次比较,找出应该插入的位置,将记录Ri插,然后将剩下的i-1个元素按关键词大小依次插入该有序序列,没插入一个元素后依然保持该序列有序,经过i-1趟排序后即成为有序序列。

每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。

2.1.2排序过程初始数据:10 3 25 20 8第一趟:[ 3 10 ] 25 20 8 (将前两个数据排序)第二趟:[ 3 10 25] 20 8 (将25 放入前面数据中的适当位置)第三趟:[ 3 10 20 25 ] 8 (将20 放入适当的位置)第四趟:[ 3 8 10 20 25 ] (将8 放入适当的位置)2.1.3时间复杂度分析直接插入排序算法必须进行n-1趟。

最好情况下,即初始序列有序,执行n-1趟,但每一趟只比较一次,移动元素两次,总的比较次数是(n-1),移动元素次数是2(n-1)。

因此最好情况下的时间复杂度就是O(n)。

最坏情况(非递增)下,最多比较i次,因此需要的比较次数是:所以,时间复杂度为O(n2)。

2.2 直接选择排序待排序的一组数据元素中,选出最小的一个数据元素与第一个位置的数据元素交换;然后在剩下的数据元素当中再找最小的与第二个位置的数据元素交换,循环到只剩下最后一个数据元素为止,依次类推直到所有记录。

第一趟第n个记录中找出关键码最小的记录与第n个记录交换;第二趟,从第二个记录开始的,2 -1个记录中再选出关键码最小的记录与第二个记录交换;如此,第i 趟,则从第i个记录开始的n - i + l个记录中选出关键码最小的记录与第i 个记录交换,直到所有记录排好序。

算法与数据结构课程设计内排序算法比较

算法与数据结构课程设计内排序算法比较
吉林大学
算法与数据结构课程设计
课程名称: 内排序算法比较
专业:计算机科学与技术 年级:
姓名:
学号:
2016 年 5 月 1 日
算法与数据结构课程设计----内排序算法比较
目录
目录..................................................................................................................................................... 2 第一章 需求分析............................................................................................................................... 3 第二章 概要设计............................................................................................................................... 3 第三章 详细设计............................................................................................................................... 3 第四章 系统实现............................................................................................................................... 5 第五章 系统测试............................................................................................................................. 11 源代码............................................................................................................................................... 16

C++与数据结构 第四次上机实验——排序

C++与数据结构 第四次上机实验——排序

[键入公司名称]数据结构实验报告——排序实验四一、实验目的和要求:1.掌握各种排序方法的排序过程;2.了解一些排序算法的实现,如插入排序、选择排序、冒泡排序、快速排序、堆排序等。

二、实验原理:1.排序的相关术语:内部排序:对内存中的数据进行排序,即排序不涉及数据内、外存交换。

外部排序:按照某种策略将外存数据分批调入内存进行排序,从而达到整体有序。

排序时涉及数据的内、外存交换。

关键字:用于标识记录的数据项。

排序方法的稳定性:具有相同关键字的记录之间相对次序保持不变的排序方法是稳定的,否则是不稳定的。

堆:关键字K1,K2,…Kn构成堆当且仅当排序满足如下性质:(1)Ki<=K2i且Ki<=K2i+1或Ki>=K2i且Ki>=K2i+1(1<=i<=n/2)就地排序:排序算法所需的辅助空间不依赖于问题的规模n.2.排序方法:插入排序:a.直接插入排序b.希尔排序:将整个待排记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

交换排序:a.冒泡排序b.快速排序:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小。

然后分别对这两部分记录继续进行排序,以达到整个序列有序。

选择排序:a.简单选择排序b.堆排序归并排序:将两个或两个以上的有序表组合成一个新的有序表。

三、实验内容:学生成绩由学生的学号、姓名和成绩组成,设计一个程序对给定的n个学生信息实现:(1)按分数的高低排序,打印每个学生在考试中的排名,分数相同的为同一名次,同一名次的同学按学号从小到大排列。

(2)按照名次列出每个学生的名次、学号、姓名和成绩。

四、程序设计:(1)程序设计思想:建立一个学生类:其中包含学生的基本信息:学号、姓名成绩以及名次。

主函数包括:学生信息输入函数:要求从键盘上输入学生的学号、姓名、以及成绩。

数据结构实验报告排序

数据结构实验报告排序

数据结构实验报告排序数据结构实验报告:排序引言:排序是计算机科学中常见的算法问题之一,它的目标是将一组无序的数据按照特定的规则进行排列,以便于后续的查找、统计和分析。

在本次实验中,我们将学习和实现几种常见的排序算法,并对它们的性能进行比较和分析。

一、冒泡排序冒泡排序是最简单的排序算法之一,它通过不断交换相邻的元素,将较大(或较小)的元素逐渐“冒泡”到数组的一端。

具体实现时,我们可以使用两层循环来比较和交换元素,直到整个数组有序。

二、插入排序插入排序的思想是将数组分为两个部分:已排序部分和未排序部分。

每次从未排序部分中取出一个元素,插入到已排序部分的适当位置,以保持已排序部分的有序性。

插入排序的实现可以使用一层循环和适当的元素交换。

三、选择排序选择排序每次从未排序部分中选择最小(或最大)的元素,与未排序部分的第一个元素进行交换。

通过不断选择最小(或最大)的元素,将其放置到已排序部分的末尾,从而逐渐形成有序序列。

四、快速排序快速排序是一种分治的排序算法,它通过选择一个基准元素,将数组划分为两个子数组,其中一个子数组的所有元素都小于等于基准元素,另一个子数组的所有元素都大于基准元素。

然后对两个子数组分别递归地进行快速排序,最终将整个数组排序。

五、归并排序归并排序也是一种分治的排序算法,它将数组划分为多个子数组,对每个子数组进行排序,然后再将排好序的子数组合并成一个有序的数组。

归并排序的实现可以使用递归或迭代的方式。

六、性能比较与分析在本次实验中,我们对以上几种排序算法进行了实现,并通过对不同规模的随机数组进行排序,比较了它们的性能。

我们使用了计算排序时间的方式,并记录了每种算法在不同规模下的运行时间。

通过对比实验结果,我们可以得出以下结论:1. 冒泡排序和插入排序在处理小规模数据时表现较好,但在处理大规模数据时性能较差,因为它们的时间复杂度为O(n^2)。

2. 选择排序的时间复杂度也为O(n^2),与冒泡排序和插入排序相似,但相对而言,选择排序的性能稍好一些。

南邮数据结构实验报告

南邮数据结构实验报告

南邮数据结构实验报告实验目的,通过本次实验,我们旨在加深对数据结构的理解,掌握数据结构的基本操作和算法设计能力,提高对数据结构的应用能力和实际问题的解决能力。

一、实验内容。

1. 实验一,线性表的基本操作。

本次实验中,我们首先学习了线性表的基本概念和操作,包括插入、删除、查找等操作,并通过实际编程操作来加深对线性表的理解。

2. 实验二,栈和队列的应用。

在实验二中,我们通过实际编程操作来学习栈和队列的应用,包括中缀表达式转换为后缀表达式、栈的应用、队列的应用等内容。

3. 实验三,树和二叉树的基本操作。

实验三中,我们学习了树和二叉树的基本概念和操作,包括树的遍历、二叉树的建立和遍历等内容,并通过实际编程操作来加深对树和二叉树的理解。

4. 实验四,图的基本操作。

最后,我们学习了图的基本概念和操作,包括图的存储结构、图的遍历等内容,并通过实际编程操作来加深对图的理解。

二、实验过程。

在实验过程中,我们首先对实验内容进行了深入的学习和理解,掌握了数据结构的基本概念和操作方法。

然后,我们通过实际编程操作来加深对数据结构的理解,并通过调试和修改程序来提高对数据结构的应用能力和实际问题的解决能力。

在实验过程中,我们遇到了一些问题,但通过不懈的努力和团队合作,最终顺利完成了实验任务。

三、实验结果与分析。

通过本次实验,我们深入理解了数据结构的基本概念和操作方法,掌握了线性表、栈、队列、树、二叉树和图的基本操作,并通过实际编程操作加深了对数据结构的理解。

同时,我们也提高了对数据结构的应用能力和实际问题的解决能力,为今后的学习和工作打下了坚实的基础。

四、实验总结。

通过本次实验,我们不仅加深了对数据结构的理解,还提高了对数据结构的应用能力和实际问题的解决能力。

在今后的学习和工作中,我们将继续努力,不断提升自己的专业能力,为将来的发展打下坚实的基础。

以上就是本次实验的报告内容,谢谢!。

数据结构中的排序算法对比

数据结构中的排序算法对比

数据结构中的排序算法对比在计算机科学领域中,排序算法是一种非常基础且重要的算法。

通过排序算法,我们可以按照一定的规则将一组数据重新排列,使其按照递增或递减的顺序呈现。

在数据结构中,有多种排序算法可供选择,每种算法都有其独特的优点和适用场景。

本文将对几种常见的排序算法进行对比和分析。

一、冒泡排序冒泡排序是最简单的排序算法之一,它的原理是通过相邻元素之间的比较和交换,每一趟循环将最大(或最小)的元素“冒泡”到最后(或最前)。

冒泡排序的时间复杂度为O(n^2),其中n为待排序数组的大小。

优点:1. 简单易懂,容易实现;2. 对小数据集执行效率较高。

缺点:1. 时间复杂度高,对于大数据集不适用;2. 效率较低,性能相对较差。

二、选择排序选择排序是一种简单直观的排序算法,它的原理是每一趟从待排序序列中选择最大(或最小)的元素,放到已排序序列的末尾(或开头)。

选择排序的时间复杂度为O(n^2)。

优点:1. 简单易懂,容易实现;2. 不占用额外的内存空间。

缺点:1. 时间复杂度高,对于大数据集不适用;2. 每一趟都需要进行元素比较,效率较低。

三、插入排序插入排序是一种简单且高效的排序算法,它的原理是将未排序部分的元素依次插入到已排序部分的合适位置。

插入排序的时间复杂度为O(n^2),其中n为待排序数组的大小。

优点:1. 简单易懂,容易实现;2. 对于小数据集和基本有序的数据集,效率较高。

缺点:1. 时间复杂度高,对于大数据集不适用;2. 每一趟都需要进行元素的比较和移动操作。

四、快速排序快速排序算法是一种高效的排序算法,它的原理是通过分治的思想将数组划分为左右两部分,左半部分的所有元素均小于右半部分的元素,然后对左右两部分分别进行快速排序。

快速排序的时间复杂度为O(nlogn)。

优点:1. 效率高,适用于各种规模的数据集;2. 对于大型数据集的排序速度较快。

缺点:1. 不稳定排序,可能导致相等元素的顺序改变;2. 需要递归操作,对于较大数据集可能会导致栈溢出。

数据结构实验报告:内部排序算法比较

数据结构实验报告:内部排序算法比较
# include "stdlib.h"
# define OVERFLOW -2
typedef struct
{ int * elem;
int length;
}SqList;
SqList create(int n)//建立一个顺序表
{ SqList L;
L.elem = (int *)malloc( n*sizeof(int));
T=QuickSort(T);
printf("排序后数据如下:\n");
for(int k=2;k<=n;k++)
printf("%6d",T.elem[k]);
printf("\n");
do
{ printf("如果想继续验证请输入Y或y,否则输入N或n:\n\n");
scanf("%s",&yes_no);
实验报告
课程名称:数据结构实验名称:内部排序算法比较任课教师:
专业:计网类班 级:2007级1班学号:
姓名:___________完成日期:2008年12月30日
一、实验目的:
掌握主要排序算法的基本思想,包括插入排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序及基数排序;掌握以上排序算法的实现方法;对各种算法的效率进行比较。
printf("%6d",L.elem[k]);
printf("\n");
}
} // InsertSort
void main()
{ SqList T;
int n=0,k,flag=0;
char yes_no;

数据结构课程设计实验报告-内部排序算法比较

数据结构课程设计实验报告-内部排序算法比较

内部排序算法比较【实验简介】1、在教科书各种内部排序算法的时间复杂度分析结果只给出了算法执行的时间的阶,或大概的执行时间,如:直接插入排序即时间复杂度为O(n*n)2、通过五组随机数据、一组正序数据与一组逆序数据比较6种常用的内部算法(起泡排序、直接插入排序、简单选择排序、快速查找排序、希尔排序、堆排序)的关键字比较次数和关键字移动次数,以取得直观感受;3、用五组不同的长度不小于100的数据进行测试,并对测试结果作出简单的分析,对得出结果拨动大小的进行解释;【设计模块】【对应模块算法说明】(1) 此算法程序中需要用到顺序表数据类型,数据元素的类型定义如下:typedef struct{KeyType key; //关键字项}RedType;typedef struct{RedType r[MAXSIZE+1]; //0号单元闲置或用作哨兵单元int length; //顺序表长度int info; //记录关键字移动次数int cmp; //关键字的比较次数}Sqlist;(2) 本实验用到六种排序算法,一个主函数和菜单函数,其中排序算法分别为起泡排序、直接插入排序、简单选择排序、快速查找排序、希尔排序、堆排序;相应时间复杂度分析如下:起泡排序:若待排序列为“正序”,则需进行一趟排序在排序过程中关键字需进行n-1次比较,无须移动纪录;若是“逆序”,则进行n-1趟排序,需n(n-1)/2次比较,并坐等数量级的移动,因此总的事件复杂度为O(n2);直接插入排序待排序纪录是随机的,关键字间的移动次数和比较次数的平均值约为n*n/4,即时间复杂度为O(n2);简单的选择排序虽然在排序过程中所需要的移动次数较少,最小时为0,最大时为3(n-1);但是关键字的比较次数总是相同的,均为n(n-1)/2,因此,时间复杂度亦为O(n2);快速排序其平均时间是kn*㏑n,其中n为待排序列中纪录的个数,k为某个常数,其时间复杂度为O(n*㏑n);希尔排序当增序序列为dlta[k]=2t-k+1-1时,时间复杂度为O(n3/2),其中t为排序趟数,1≤k≤t≤㏒2(n+1);堆排序此排序对于含n个元素的序列排序时,总共进行的关键字比较次数不超过4n,且在最坏的情况下,其时间复杂度为O(n*㏑n);算法分析如下:①冒泡排序该算法的的思路是首先将第1个记录的关键字负值给L.r[0],然后用L.r[0]与第(i+1)个记录的关键字比较,若为逆序,则交换第i与第i+1两记录的位置,然后让i加1,重复以上操作,直至i=n-1为止;依次进行第二趟、第三趟……作同样的操作,直至所有的记录按正序排列(一般需要n-1趟比较,第i趟从L.r[1]到L.r[n-i+1]依次比较,1≦ i ≦n-i,比较结果是让其中最大的记录放在L.r[n-i+1]的位置)void BubbleSort(Sqlist *L) //冒泡排序{for(i=0;i<L->length;i++){L->r[0]=L->r[1];for(j=1;j<N-i;j++)if(L->r[0].key>=L->r[j+1].key)L->r[j] L->r[j+1]; //交换两记录的位置elseL->r[0]=L->r[j+1]; //保证L->r[0]始终为较大的记录L->r[j+1]=L->r[0]; //把最大的记录放到祠堂排序的最高位置}printf(L->r[MAXSIZE]);//输出排序后数组和相关数据}②直接插入排序本算法的思路是,把L->r[0]设置为哨兵,排序时把第i个记录复制给哨兵,并于其前的i-1个记录进行比较,找到第一个比起大的记录,利用循环让记录后移,把其放到第一个比起大的记录前面。

南邮算法实验报告

南邮算法实验报告

一、实验目的本次实验旨在通过实际操作,加深对算法理论知识的理解,提高算法设计与分析能力,培养解决实际问题的能力。

通过实验,使学生掌握以下内容:1. 理解常见算法的基本原理和实现方法;2. 掌握算法设计与分析的常用方法;3. 能够运用算法解决实际问题。

二、实验内容本次实验选择了以下两个算法进行实现和分析:1. 冒泡排序算法;2. 快速排序算法。

三、实验过程1. 冒泡排序算法(1)算法原理冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。

遍历数列的工作是重复地进行,直到没有再需要交换,也就是说该数列已经排序完成。

(2)实现步骤① 初始化一个布尔变量 swapped,用于判断是否发生交换;② 遍历数组,比较相邻的两个元素,如果前者大于后者,则交换它们的位置;③ 如果在一轮遍历中没有发生交换,则说明数组已经排序完成,退出循环;④ 重复步骤②和③,直到数组排序完成。

(3)代码实现```pythondef bubble_sort(arr):n = len(arr)for i in range(n):swapped = Falsefor j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]swapped = Trueif not swapped:breakreturn arr```2. 快速排序算法(1)算法原理快速排序是一种分而治之的排序算法。

基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

(2)实现步骤① 选择一个基准值(pivot),可以是数组的第一个元素、最后一个元素或中间元素;② 将数组分为两部分,一部分是小于基准值的元素,另一部分是大于基准值的元素;③ 对这两部分数据分别进行快速排序;④ 递归执行步骤①至③,直到数组排序完成。

数据结构实验四排序

数据结构实验四排序

数据结构实验四排序数据结构实验报告实验名称:实验四——排序学⽣姓名:⼤学霸班级:xxxxxxxxxx班内序号:xx学号:xxxxxxxxxx⽇期:2012年12⽉14⽇1.实验要求a. 实验⽬的通过实现下述实验内容,学习、实现、对⽐各种排序算法,掌握各种排序算法的优劣,以及各种算法使⽤的情况。

b. 实验内容使⽤简单数组实现下⾯各种排序算法,并进⾏⽐较。

排序算法:1、插⼊排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,⽐较上述排序算法中关键字的⽐较次数和移动次数(其中关键字交换计为3次移动)。

3、对于这三类数据,⽐较上述排序算法中不同算法的执⾏时间,精确到微秒(选作)4、对2和3的结果进⾏分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。

2. 程序分析2.1 存储结构排序时所⽤数据均为长整型数组a[Maxsize+1],即静态链表。

数组a[0]不存数据,排序时作为临时存储,从a[1]开始存储数据,共有Maxsize个数据。

2.2 关键算法分析核⼼算法思想:1. 结合教材上所讲,⽤排序类Sort来实现7种不同的排序算法,统计每次排序后的数据,进⾏下依次排序。

2. 实验测试数据分为三类:正序,逆序,随机数据。

所以要对Sort类中的数组放置三种不同的数据。

第⼀次先测试随机数据的七种排序,然后测试正序数据的七种排序,最后测试逆序数据的七种排序。

3. 将各个排序函数封装成sort类,加⼊统计次数,耗费时间,打印数据等成员函数,测试序列为sort类的私有成员,排序次数和时间会保存在sort类的数组型成员中,最后打印输出。

排序时就调⽤相应成员函数,共同⼯作。

关键算法1:实验要求的七种排序的基本排序功能。

1、插⼊排序:每次将⼀个待排序的元素按其关键码的⼤⼩插⼊到⼀个已经排序好的有序序列中,直到全部元素排序好。

南邮数据结构实验报告

南邮数据结构实验报告

南邮数据结构实验报告南邮数据结构实验报告一、实验目的和背景数据结构是计算机科学中非常重要的一门基础课程,它研究了数据的组织、存储和管理方式,是计算机程序设计的基础。

本次实验旨在通过对南京邮电大学数据结构实验的学习和实践,加深对数据结构相关概念和算法的理解,并掌握数据结构在实际问题中的应用。

二、实验内容本次实验涉及到以下几个数据结构的实现和应用:1. 线性表:线性表是最简单的一种数据结构,它包括顺序表和链表两种实现方式。

我们需要实现线性表的基本操作,如插入、删除、查找等,并通过实际案例加深对线性表的理解。

2. 栈和队列:栈和队列是两种特殊的线性表,它们的插入和删除操作都受限制。

我们需要实现栈和队列的基本操作,并通过实例分析它们在实际问题中的应用。

3. 二叉树:二叉树是一种重要的非线性数据结构,它具有良好的递归性质。

我们需要实现二叉树的创建、遍历和查找等操作,并通过实例研究二叉树在排序和搜索问题中的应用。

4. 图:图是一种复杂的非线性数据结构,它由节点和边组成。

我们需要实现图的创建、遍历和最短路径等操作,并通过实例研究图在网络和路径规划等问题中的应用。

三、实验过程和结果在实验过程中,我们首先学习了相关的数据结构概念和算法原理,并通过编程语言实现了上述数据结构的基本操作。

在实验过程中,我们遇到了一些问题,如内存泄漏、指针操作错误等,但通过调试和修改代码,最终成功实现了各个数据结构的功能。

在实验结果方面,我们通过自己编写的测试用例对实现的数据结构进行了验证。

例如,对于线性表的插入和删除操作,我们分别测试了在表头、表尾和表中插入或删除元素的情况,并验证了操作的正确性。

对于二叉树的遍历操作,我们通过构建不同形态的二叉树,验证了前序、中序和后序遍历的正确性。

四、实验总结和心得体会通过本次实验,我们深入了解了数据结构的基本概念和常用算法,掌握了数据结构在实际问题中的应用。

同时,我们也意识到了数据结构的重要性和实践的必要性。

数据结构排序实验报告

数据结构排序实验报告

引言概述:数据结构排序实验是计算机科学与技术专业中一项重要的实践课程。

通过实验,可以深入理解和掌握不同排序算法的原理、特点和性能表现。

本文将针对数据结构排序实验进行详细的阐述和总结,包括实验目的、实验内容、实验结果分析和总结。

一、实验目的1. 加深对数据结构排序算法的理解:通过实验,掌握不同排序算法的工作原理和实现方式。

2. 分析和比较不同排序算法的性能:对比不同排序算法在不同数据规模下的时间复杂度和空间复杂度,理解它们的优劣势。

3. 提高编程和算法设计能力:通过实验的编写,提升对排序算法的实现能力和代码质量。

二、实验内容1. 选择排序算法:选择排序是一种简单直观的排序算法,将序列分为有序和无序两部分,每次从无序部分选择最小(最大)元素,放到有序部分的末尾(开头)。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析2. 插入排序算法:插入排序逐步构建有序序列,对于未排序的元素,在已排序序列中从后向前扫描,找到对应位置插入。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析3. 快速排序算法:快速排序利用分治的思想,将序列分为左右两部分,选取基准元素,将小于基准的放在左边,大于基准的放在右边,递归地对左右部分进行排序。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析4. 归并排序算法:归并排序是一种稳定的排序算法,通过将序列分为若干子序列,分别进行排序,然后再将排好序的子序列合并成整体有序序列。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析5. 堆排序算法:堆是一种特殊的树状数据结构,堆排序利用堆的性质进行排序,通过构建大顶堆或小顶堆,并逐个将堆顶元素移出形成有序序列。

- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析三、实验结果分析1. 比较不同排序算法的执行时间:根据实验数据和分析,对比不同排序算法在不同数据规模下的执行时间,并针对其时间复杂度进行验证和分析。

数据结构课程设计实验报告(各种排序的实现与效率分析)

数据结构课程设计实验报告(各种排序的实现与效率分析)

数据结构课程设计实验报告1、需求分析(1)对起泡排序、直接排序、简单选择排序、快速排序、希尔排序、堆排序算法进行比较;(2)待排序表的表长不小于100,表中数据随机产生,至少用5组不同数据作比较,比较指标有:关键字参加比较次数和关键字的移动次数(关键字进行一次交换操作记为3次移动);(3)输出比较结果。

2、主要函数及数据类型typedef int KeyType; //定义关键字类型为整数类型typedef int InfoType; //定义关键字类型为整数类型typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等*/typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef struct{KeyType key; //关键字项InfoType otherinfo; //其它数据项}RedType; //记录类型typedef struct {RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元int length; //顺序表长度}SqList; //顺序表类型3、源代码/*头文件和宏定义部分*/#include"string.h"#include"ctype.h"#include"time.h"#include"malloc.h" /* malloc()等*/#include"limits.h" /* INT_MAX等*/#include"stdio.h" /* EOF(=^Z或F6),NULL */#include"stdlib.h" /* atoi() */#include"io.h" /* eof() */#include"math.h" /* floor(),ceil(),abs() */#include"process.h" /* exit() *//* 函数结果状态代码*/#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define MAXSIZE 100 //示例数据类型的最大长度typedef int KeyType; //定义关键字类型为整数类型typedef int InfoType; //定义关键字类型为整数类型typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等*/ typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef struct{KeyType key; //关键字项InfoType otherinfo; //其它数据项}RedType; //记录类型typedef struct {RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元int length; //顺序表长度}SqList; //顺序表类型void InitData(SqList *L,int dataCopy[]){int i;L->length=MAXSIZE;srand((unsigned)time(NULL));for(i=0;i<=MAXSIZE;i++){L->r[i].otherinfo=0;dataCopy[i]=L->r[i].key=rand();}}void PrintData(SqList L){int i;for(i=1;i<=L.length;i++){printf("%d\t",L.r[i].key);}}void ResumeData(SqList *L,int dataCopy[]){int i;for(i=0;i<=MAXSIZE;i++){L->r[i].key=dataCopy[i];}}void PrintStatistic(int *compareCounts,int *moveCounts){printf("\n\t\t各种排序方法比较结果:\n\n");printf("\t\t起泡排序: 比较次数%d,移动次数%d\n",compareCounts[0],moveCounts[0]);printf("\t\t直接插入排序:比较次数%d,移动次数%d\n",compareCounts[1],moveCounts[1]);printf("\t\t简单选择排序:比较次数%d,移动次数%d\n",compareCounts[2],moveCounts[2]);printf("\t\t快速排序: 比较次数%d,移动次数%d\n",compareCounts[3],moveCounts[3]);printf("\t\t希尔排序: 比较次数%d,移动次数%d\n",compareCounts[4],moveCounts[4]);printf("\t\t堆排序: 比较次数%d,移动次数%d\n",compareCounts[5],moveCounts[5]);}/*******************************直接插入排序*******************************/void InsertSort(SqList *L,int *compareCounts,int *moveCounts ) //直接插入排序{int i,j; //for(i=2;i<=L->length;i++) //从顺序表的第二个元素开始进行比较{if(L->r[i].key<L->r[i-1].key) //将每个元素与它的前一个元素关键字进行比较{L->r[0]=L->r[i]; //如果关键字比前一个元素关键字小,就将元素复制作为哨兵L->r[i]=L->r[i-1];(*moveCounts)+=2; //关键字移动了2次j=i-2; //从要比较的关键字的前第二个记录开始进行比较,然后后移while(L->r[0].key<L->r[j].key){L->r[j+1]=L->r[j]; //记录后移(*moveCounts)++; //每作一次后移,移动次数加1j--;(*compareCounts)++; //每作一次比较,比较次数加1}L->r[j+1]=L->r[0]; //插入到正确位置}(*compareCounts)++;}}/*******************************希尔排序*******************************/void ShellInsert(SqList *L,int increment,int *compareCounts,int *moveCounts){ //对顺序表作一趟希尔插入排序int j,n;for(j=1+increment;j<=L->length;j++){if(L->r[j].key<L->r[j-increment].key) //将L->[i]插入到有序增量子表{L->r[0]=L->r[j]; //暂存在L->r[0]L->r[j]=L->r[j-increment];(*moveCounts)+=2;for(n=j-2*increment;n>0&&L->r[0].key<L->r[n].key;n-=increment){L->r[n+increment]=L->r[n]; //记录后移,查找插入位置(*moveCounts)++;(*compareCounts)++;}L->r[n+increment]=L->r[0]; //插入(*moveCounts)++;}(*compareCounts)++;}}void ShellSort(SqList *L,int IncreList[],int times,int *compareCounts,int *moveCounts) //希尔排序{ //按增量序列Increlist[0.....times-1]对顺序表L作希尔排序int k; //for(k=0;k<times;k++){ShellInsert(L,IncreList[k],compareCounts,moveCounts); //一趟增量为IncreList[k]的插入排序}}/*******************************起泡排序*******************************/void BubbleSort(SqList *L,int *compareCounts,int *moveCounts) //起泡排序{int i,j;for(i=1;i<=L->length;i++){for(j=L->length;j>i;j--){ //从后往前两两进行比较,将元素关键字小的交换到前面if(L->r[j].key<L->r[j-1].key){L->r[0]=L->r[j];L->r[j]=L->r[j-1];L->r[j-1]=L->r[0];(*moveCounts)+=3;}(*compareCounts)++;}}}/*******************************快速排序*******************************/int Partition(SqList *L,int low,int high,int *compareCounts,int *moveCounts) //快速排序中的分{int pivotkey;L->r[0]=L->r[low];(*moveCounts)++;pivotkey=L->r[low].key;while(low<high){while(low<high&&L->r[high].key>=pivotkey){high--;(*compareCounts)++;}L->r[low]=L->r[high];(*moveCounts)++;while(low<high&&L->r[low].key<=pivotkey){low++;(*compareCounts)++;}L->r[high]=L->r[low];(*moveCounts)++;(*compareCounts)++;}L->r[low]=L->r[0];(*moveCounts)++;return low;}void QSort(SqList *L,int low,int high,int *compareCounts,int *moveCounts){int pivotloc;if(low<high){pivotloc=Partition(L,low,high,compareCounts,moveCounts);QSort(L,low,pivotloc-1,compareCounts,moveCounts);QSort(L,pivotloc+1,high,compareCounts,moveCounts);}}void QuickSort(SqList *L,int *compareCounts,int *moveCounts){QSort(L,1,L->length,compareCounts,moveCounts);}/*******************************简单选择排序*******************************/void SelectSort(SqList *L,int *compareCounts,int *moveCounts){int i,j,minPoint;for(i=1;i<=L->length;i++){L->r[0]=L->r[i];(*moveCounts)++;minPoint=i;for(j=i+1;j<=L->length;j++){if(L->r[j].key<L->r[0].key){L->r[0]=L->r[j];(*moveCounts)++;minPoint=j;}(*compareCounts)++;}L->r[minPoint]=L->r[i];L->r[i]=L->r[0];(*moveCounts)++;}}/*******************************堆排序*******************************/void HeapAdjust(SqList *L,int s,int m,int *compareCounts,int *moveCounts){RedType cmpKey; //待比较的值int j;cmpKey=L->r[s];(*moveCounts)++;for(j=s*2;j<=m;j*=2){(*compareCounts)+=2;if(j<m&&L->r[j].key<L->r[j+1].key) j++;if(!(cmpKey.key<L->r[j].key)) break;L->r[s]=L->r[j];(*moveCounts)++;s=j;}L->r[s]=cmpKey;(*moveCounts)++;}void HeapSort(SqList *L,int *compareCounts,int *moveCounts){int i;RedType temp;for(i=L->length/2;i>0;i--) HeapAdjust(L,i,L->length,compareCounts,moveCounts);for(i=L->length;i>1;i--){temp=L->r[1];L->r[1]=L->r[i];L->r[i]=temp;(*moveCounts)+=3;HeapAdjust(L,1,i-1,compareCounts,moveCounts);}}void SortCompare(){SqList L; //用顺序表存放待排序的元素int dataCopy[MAXSIZE+1],i;int compareCounts[7],moveCounts[7];int increList[6];for(i=0;i<5;i++){increList[i]=(int)pow(2,7-i)-1;}increList[5]=1;for(i=0;i<7;i++){compareCounts[i]=0;moveCounts[i]=0;}InitData(&L,dataCopy); //初始化数据,随机产生100个正整数的数列printf("\t\t\t初始化数据后产生的数列:\n");PrintData(L); //显示出未排序的数列printf("\n\n\t\t\t经过起泡排序后产生的数列:\n");BubbleSort(&L,&compareCounts[0],&moveCounts[0]); //对数列使用起泡排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过直接插入排序后产生的数列:\n");InsertSort(&L,&compareCounts[1],&moveCounts[1]); //对数列使用插入排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过简单选择排序后产生的数列:\n");SelectSort(&L,&compareCounts[2],&moveCounts[2]); //对数列使用简单选择排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过快速排序后产生的数列:\n");QuickSort(&L,&compareCounts[3],&moveCounts[3]); //对数列使用快速排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过希尔排序后产生的数列:\n");ShellSort(&L,increList,6,&compareCounts[4],&moveCounts[4]); //对数列使用希尔排序PrintData(L); //显示出排序好的数列ResumeData(&L,dataCopy);printf("\n\n\t\t\t经过堆排序后产生的数列:\n");HeapSort(&L,&compareCounts[5],&moveCounts[5]); //对数列使用堆排序PrintData(L); //显示出排序好的数列PrintStatistic(compareCounts,moveCounts);}main(){int i,temp;for(i=0;i<5;i++){SortCompare();printf("\n\t\t请按任意键进行下一组数据的排序对比\n\n");temp=getchar();}}4、调试分析成功运行,如图所示:。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告(2015 / 2016学年第二学期)课程名称数据结构A实验名称内排序算法的实现以及性能比较实验时间2016 年 5 月26 日指导单位计算机科学与技术系指导教师骆健学生姓名耿宙班级学号B********学院(系) 管理学院专业信息管理与信息系统——实习题名:内排序算法的实现及性能比较班级 B141116 姓名耿宙学号 B14111615 日期2016.05.26 一、问题描述验证教材的各种内排序算法,分析各种排序算法的时间复杂度;改进教材中的快速排序算法,使得当子集合小于10个元素师改用直接插入排序;使用随即数发生器产生大数据集合,运行上述各排序算法,使用系统时钟测量各算法所需的实际时间,并进行比较。

系统时钟包含在头文件“time.h”中。

二、概要设计文件Sort.cpp中包括了简单选择排序SelectSort(),直接插入排序InsertSort(),冒泡排序BubbleSort(),两路合并排序Merge(),快速排序QuickSort()以及改进的快速排序GQuickSort()六个内排序算法函数。

主主函数main的代码如下图所示:三、详细设计1.类和类的层次设计在此次程序的设计中没有进行类的定义。

程序的主要设计是使用各种内排序算法对随机生成的数列进行排列,并进行性能的比较,除此之外还对快速排序进行了改进。

下图为主函数main的流程图:——main()2.核心算法1)简单选择排序:简单选择排序的基本思想是:第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。

2)直接插入排序:插入排序的思想是将一组无序的元素分别插入一个已经有序的的数组里,并保证插入后的数组也是有序的。

当所有无序组的元素都插入完毕时,一个有序数组构造完成。

数组n[1…r]为初始的一个无序数组(为了直观起见,我们这里设定数组从1开始,而不是0),则n[1]默认为只有一个元素的有序数组,n[2]插入只有n[1]构成的有序数组中,则此时有序数组的元素数量变为2。

以此类推,到第i个元素时,前i-1个元素已经是有序的,此时只需将第i个元素插入到有序数组中并使之保持有序。

如此直至最后一个元素插入完毕,整个插入排序完成。

3)冒泡排序:冒泡排序每遍历一次数组,便将最大的元素放到数组最后边。

下次遍历将次大的元素放到数组倒数第二位,依次类推,直至将最小的元素放到最前边,此时冒泡排序完成。

4)快速排序:快速排序是采用了分而治之的思想,但与合并排序有所不同的是快速排序先“工作”(这里是分割或partition),再递归。

快速排序的主要思想是保证数组前半部分小于后半部分的元素,然后分别对前半部分和后半部分再分别进行排序,直至所有元素有序。

5)两路合并排序两路合并排序算法的基本思想是:将待排序元素平分成大小大致相同的两个子序列,然后对每个子序列分别使用递归的方法进行两路合并排序,直到子序列长度变为1,最后利用合并算法将得到的已排序好的两个子序列合并成一个有序的序列。

两路合并排序算法的核心部分是将子问题的解组合成原问题解得合并操作。

常用的操作是新建一个序列,序列的大小等于要合并的两个子序列的长度之和。

比较两个子序列中的最小值,输出其中较小者到新建的序列中,重复此过程直到其中一个子序列为空。

如果另一个子序列中还有元素未输出,则将剩余元素依次输出到新建序列中即可。

最终得到一个有序序列。

此外还对快速排序进行了改进,改进算法流程图如下所示:GQuickSort () 四、程序代码template<class T>void GQuickSort(T A[],int n) //改进的快速排序{GQSort(A,0,n-1);}template<class T>void GQSort(T A[],int left,int right){int i,j;——if(right>=9){if(left<right){i=left;j=right+1;do{do i++;while (A[i]<A[left]);do j--;while (A[j]>A[left]);if(i<j)Swap(A[i],A[j]);}while(i<j);Swap(A[left],A[j]);QSort(A,left,j-1);QSort(A,j+1,right);}}else{InsertSort(A,right-left+1);return ;}}五、测试和调试1.测试用例和结果测试结果如下图1)生成随机数据2)简单选择排序及其所需时间3)直接插入排序及其所需时间4)冒泡排序及其所需时间5)快速排序及其所需时间6)改进快速排序及其所需时间7)两路合并排序及其所需时间2.结果分析简单选择排序的最好、最坏的平均情况的时间复杂度都为O(n2),是不稳定的排序方法;直接插入排序的最好情况的时间复杂度为O(n),最坏情况的时间复杂度为O(n2);冒泡排序最好情况的时间复杂度为O(n),最坏情况的时间复杂度为O(n2),是稳定的排序方法;快速排序最好情况的时间复杂度为O(n2),最坏情况的时间复——杂度为O(nlog2n),是不稳定的排序方法;两路合并排序的时间复杂度为O(nlog2n),是稳定的排序方法。

六、实习小结在这次实验中,我们对内部排序算法进行了比较以及性能分析,通过这次实验,我们加深了对内部排序算法的理解,对内部排序算法的基本运算的实现有所掌握,对课本中所学的各种数据结构进一步理解和掌握,学会了如何把学到的知识用于解决实际问题,锻炼了自己动手的能力。

通过这次实验,我明白了,没有总是最好的排序方法。

对于一般列表,快速排序、希的性能较好。

通过本次实验,我深刻体会到问题解决方案的重要性,算法效率分析的必要性。

法时。

——附录:#include<iostream.h>#include<stdlib.h>#include<time.h>template<class T>void Swap(T &a,T &b){T temp=a;a=b;b=temp;}template<class T>void SelectSort(T A[],int n) //简单选择排序{int small;for(int i=0;i<n-1;i++){small=i;for(int j=i+1;j<n;j++)if(A[j]<A[small])small=j;Swap(A[i],A[small]);}}template<class T>void InsertSort(T A[],int n) //直接插入排序{for(int i=1;i<n;i++){int j=i;T temp=A[j];while(j>0&&temp<A[j-1]){A[j]=A[j-1];j--;}A[j]=temp;}}template<class T>void BubbleSort(T A[],int n) //冒泡排序{int i,j,last;——i=n-1;while(i>0){last=0;for(j=0;j<i;j++)if(A[j+1]<A[j]){Swap(A[j],A[j+1]);last=j;}i=last;}}template<class T>void QuickSort(T A[],int n) //快速排序{QSort(A,0,n-1);}template<class T>void QSort(T A[],int left,int right){int i,j;if(left<right){i=left;j=right+1;do{do i++;while (A[i]<A[left]);do j--;while (A[j]>A[left]);if(i<j)Swap(A[i],A[j]);}while(i<j);Swap(A[left],A[j]);QSort(A,left,j-1);QSort(A,j+1,right);}}template<class T>void GQuickSort(T A[],int n) //改进的快速排序{GQSort(A,0,n-1);}template<class T>——void GQSort(T A[],int left,int right){int i,j;if(right>=9){if(left<right){i=left;j=right+1;do{do i++;while (A[i]<A[left]);do j--;while (A[j]>A[left]);if(i<j)Swap(A[i],A[j]);}while(i<j);Swap(A[left],A[j]);QSort(A,left,j-1);QSort(A,j+1,right);}}else{InsertSort(A,right-left+1);return ;}}template<class T>void Merge(T A[],int i1,int j1,int i2,int j2) //两路合并排序{T* Temp=new T[j2-i1+1];int i=i1,j=i2,k=0;while(i<=j1&&j<=j2){if(A[i]<=A[j])Temp[k++]=A[i++];else Temp[k++]=A[j++];}while (i<=j1)Temp[k++]=A[i++];while(j<=j2)Temp[k++]=A[j++];for(i=0;i<k;i++)A[i1++]=Temp[i];——delete[] Temp;}template<class T>void MergeSort(T A[],int n){int i1,j1,i2,j2;int size=1;while(size<n){i1=0;while(i1+size<n){i2=i1+size;j1=i2-1;if(i2+size-1>n-1)j2=n-1;elsej2=i2+size-1;Merge(A,i1,j1,i2,j2);i1=j2+1;}size*=2;}}int main(){clock_t start,finish;srand(time(NULL));int n=1000;int *a=new int[n];int *b=new int[n];int *c=new int[n];int *d=new int[n];int *e=new int[n];int *f=new int[n];cout<<"待排序序列为:"<<endl;for(int i=0;i<n;i++){a[i]=rand()%91;cout<<a[i]<<" ";b[i]=a[i];c[i]=a[i];d[i]=a[i];——e[i]=a[i];f[i]=a[i];}cout<<endl;start=clock();SelectSort(a,n);cout<<"经过简单选择排序后的序列为:"<<endl;for(i=0;i<n;i++)cout<<a[i]<<" ";cout<<endl;finish=clock();cout<<"开始时间为:"<<start<<" "<<"结束时间为:"<<finish<<" "<<"持续时间为:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;start=clock();InsertSort(b,n);cout<<"经过直接插入排序后的序列为:"<<endl;for(i=0;i<n;i++)cout<<b[i]<<" ";cout<<endl;finish=clock();cout<<"开始时间为:"<<start<<" "<<"结束时间为:"<<finish<<" "<<"持续时间为:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;start=clock();BubbleSort(c,n);cout<<"经过冒泡排序后的序列为:"<<endl;for(i=0;i<n;i++)cout<<c[i]<<" ";cout<<endl;finish=clock();cout<<"开始时间为:"<<start<<" "<<"结束时间为:"<<finish<<" "<<"持续时间为:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;start=clock();QuickSort(d,n);cout<<"经过快速排序后的序列为:"<<endl;for(i=0;i<n;i++)cout<<d[i]<<" ";cout<<endl;finish=clock();cout<<"开始时间为:"<<start<<" "<<"结束时间为:"<<finish<<" "<<"持续时间为:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;start=clock();MergeSort(e,n);cout<<"经过两路合并排序后的序列为:"<<endl;for(i=0;i<n;i++)——cout<<e[i]<<" ";cout<<endl;finish=clock();cout<<"开始时间为:"<<start<<" "<<"结束时间为:"<<finish<<" "<<"持续时间为:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;start=clock();GQuickSort(f,n);cout<<"经过改进后的快速排序后的序列为:"<<endl;for(i=0;i<n;i++)cout<<f[i]<<" ";cout<<endl;finish=clock();cout<<"开始时间为:"<<start<<" "<<"结束时间为:"<<finish<<" "<<"持续时间为:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;return 0;}。

相关文档
最新文档