数据结构课程设计_排序算法比较【完整版】
- 格式:doc
- 大小:164.00 KB
- 文档页数:15
数据结构课程设计—内部排序算法比较在计算机科学领域中,数据的排序是一项非常基础且重要的操作。
内部排序算法作为其中的关键部分,对于提高程序的运行效率和数据处理能力起着至关重要的作用。
本次课程设计将对几种常见的内部排序算法进行比较和分析,包括冒泡排序、插入排序、选择排序、快速排序和归并排序。
冒泡排序是一种简单直观的排序算法。
它通过重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。
这种算法的优点是易于理解和实现,但其效率较低,在处理大规模数据时性能不佳。
因为它在最坏情况下的时间复杂度为 O(n²),平均时间复杂度也为O(n²)。
插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,直到整个序列有序。
插入排序在数据量较小时表现较好,其平均时间复杂度和最坏情况时间复杂度也都是 O(n²),但在某些情况下,它的性能可能会优于冒泡排序。
选择排序则是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。
以此类推,直到全部待排序的数据元素排完。
选择排序的时间复杂度同样为O(n²),但它在某些情况下的交换操作次数可能会少于冒泡排序和插入排序。
快速排序是一种分治的排序算法。
它首先选择一个基准元素,将数列分成两部分,一部分的元素都比基准小,另一部分的元素都比基准大,然后对这两部分分别进行快速排序。
快速排序在平均情况下的时间复杂度为 O(nlogn),最坏情况下的时间复杂度为 O(n²)。
然而,在实际应用中,快速排序通常表现出色,是一种非常高效的排序算法。
归并排序也是一种分治算法,它将待排序序列分成若干个子序列,每个子序列有序,然后将子序列合并成一个有序序列。
数据结构实验报告本文是范文,仅供参考写作,禁止抄袭本文内容上传提交,违者取消写作资格,成绩不合格!实验名称:排序算法比较提交文档学生姓名:提交文档学生学号:同组成员名单:指导教师姓名:排序算法比较一、实验目的和要求1、设计目的1.掌握各种排序的基本思想。
2.掌握各种排序方法的算法实现。
3.掌握各种排序方法的优劣分析及花费的时间的计算。
4.掌握各种排序方法所适应的不同场合。
2、设计内容和要求利用随机函数产生30000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并统计每一种排序上机所花费的时间二、运行环境(软、硬件环境)软件环境:Vc6.0编程软件运行平台: Win32硬件:普通个人pc机三、算法设计的思想1、冒泡排序: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趟,或者不需再交换记录时为止。
2、选择排序:selSort()每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序不像冒泡排序算法那样先并不急于调换位置,第一轮(k=1)先从array[k]开始逐个检查,看哪个数最小就记下该数所在的位置于minlIndex中,等一轮扫描完毕,如果找到比array[k-1]更小的元素,则把array[minlIndex]和a[k-1]对调,这时array[k]到最后一个元素中最小的元素就换到了array[k-1]的位置。
数据结构的常用算法一、排序算法排序算法是数据结构中最基本、最常用的算法之一。
常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、归并排序等。
1. 冒泡排序冒泡排序是一种简单的排序算法,它重复地比较相邻的两个元素,如果它们的顺序错误就将它们交换过来。
通过多次的比较和交换,最大(或最小)的元素会逐渐“浮”到数列的顶端,从而实现排序。
2. 选择排序选择排序是一种简单直观的排序算法,它每次从待排序的数据中选择最小(或最大)的元素,放到已排序序列的末尾,直到全部元素排序完毕。
3. 插入排序插入排序是一种简单直观的排序算法,它将待排序的数据分为已排序区和未排序区,每次从未排序区中取出一个元素,插入到已排序区的合适位置,直到全部元素排序完毕。
4. 快速排序快速排序是一种常用的排序算法,它采用分治的思想,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分小,然后再按此方法对这两部分数据进行快速排序,递归地进行,最终实现整个序列有序。
5. 归并排序归并排序是一种稳定的排序算法,它采用分治的思想,将待排序的数据分成若干个子序列,分别进行排序,然后将排好序的子序列合并成更大的有序序列,直到最终整个序列有序。
二、查找算法查找算法是在数据结构中根据给定的某个值,在数据集合中找出目标元素的算法。
常见的查找算法有线性查找、二分查找、哈希查找等。
1. 线性查找线性查找是一种简单直观的查找算法,它从数据集合的第一个元素开始,依次比较每个元素,直到找到目标元素或遍历完整个数据集合。
2. 二分查找二分查找是一种高效的查找算法,它要求数据集合必须是有序的。
通过不断地将数据集合分成两半,将目标元素与中间元素比较,从而缩小查找范围,最终找到目标元素或确定目标元素不存在。
3. 哈希查找哈希查找是一种基于哈希表的查找算法,它通过利用哈希函数将目标元素映射到哈希表中的某个位置,从而快速地找到目标元素。
三、图算法图算法是解决图结构中相关问题的算法。
一、设计思想排序是数据处理中使用频率很高的一种操作,是数据查询之前需要进行的一项基础操作。
它是将任意序列的数据元素(或记录)按关键字有序(升序或降序)重新排列的过程。
排序的过程中有两种基本操作:一是比较两个关键字的值;二是根据比较结果移动记录位置。
排序的算法有很多种,这里仅对插入排序、选择排序、希尔排序、归并排序和快速排序作了比较。
直接插入排序算法基本思路:直接插入排序时将一个元素插入已排好的有序数组中,从而得到一个元素个数增加1的新的有序数组。
其具体实现过程是,将第i个元素与已经排好序的i-1个元素依次进行比较,再将所有大于第i个元素的元素后移一个位置,直到遇到小于或等于第i个元素,此时该元素的后面一个位置为空,将i元素插入此空位即可。
选择排序算法基本思路:定义两个数组sela[]和temp[],sela[]用来存放待排序数组,temp[]用来存放排好序的数组。
第一趟,将sela[]数组中n个元素进行比较,找出其中最小的元素放入temp[]的第一个位置,同时将sela[]中将该元素位置设置为无穷大。
第二趟,将sela[]数组中n个元素进行比较,找出其中最小的元素放入temp[]的第二个位置,同时将sela[]中将该元素位置设置为无穷大。
以此类推,n趟后将sela[]中所有元素都已排好序放入temp[]数组中。
希尔排序算法基本思路:希尔排序又称为变长步径排序,它也是一种基于插入排序的思想。
其基本思路是,定义一个步长数组gaps[1,5,13,43……],先选取合适的大步长gap将整个待排序的元素按步长gap分成若干子序列,第一个子序列的元素为a[0]、a[0+gap]、a[0+2gap]……a[0+k*gap];第二列为a[1]、a[1+gap]、a[1+2gap]……a[1+k*gap];……。
然后,对这些子序列分别进行插入排序,然后将gap按gaps[]数组中的步长缩小,按缩小后的步长再进行子序列划分排序,再减小步长直到步长为1为止。
《数据结构与算法》实验报告一、需求分析问题描述:在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。
试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。
基本要求:(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].num<=RandArray[i]; L->Length<=i;}BOOL LT(int i, int j,int* CmpNum){(*CmpNum)++; 若i<j) 则返回TRUE; 否则返回FALSE;}void Display(LinkList* L){FILE* f; //定义一个文件指针f int i;若打开文件的指令不为空则//通过文件指针f打开文件为条件判断{ //是否应该打开文件输出“can't open file”;exit(0); }for (i=0; i小于L->Length; i++)fprintf(f,"%d\n",L->Record[i].num);通过文件指针f关闭文件;三、调试分析1.调试过程中遇到的问题及经验体会:在本次程序的编写和调试过程中,我曾多次修改代码,并根据调试显示的界面一次次调整代码。
内部排序算法比较第一章问题描述排序是数据结构中重要的一个部分,也是在实际开发中易遇到的问题,所以研究各种排算法的时间消耗对于在实际应用当中很有必要通过分析实际结合算法的特性进行选择和使用哪种算法可以使实际问题得到更好更充分的解决!该系统通过对各种内部排序算法如直接插入排序,冒泡排序,简单选择排序,快速排序,希尔排序,堆排序、二路归并排序等,以关键码的比较次数和移动次数分析其特点,并进行比较,估算每种算法的时间消耗,从而比较各种算法的优劣和使用情况!排序表的数据是多种不同的情况,如随机产生数据、极端的数据如已是正序或逆序数据。
比较的结果用一个直方图表示。
第二章系统分析界面的设计如图所示:|******************************||-------欢迎使用---------||-----(1)随机取数-------||-----(2)自行输入-------||-----(0)退出使用-------||******************************|请选择操作方式:如上图所示该系统的功能有:(1):选择 1 时系统由客户输入要进行测试的元素个数由电脑随机选取数字进行各种排序结果得到准确的比较和移动次数并打印出结果。
(2)选择 2 时系统由客户自己输入要进行测试的元素进行各种排序结果得到准确的比较和移动次数并打印出结果。
(3)选择0 打印“谢谢使用!!”退出系统的使用!!第三章系统设计(I)友好的人机界面设计:(如图3.1所示)|******************************||-------欢迎使用---------||-----(1)随机取数-------||-----(2)自行输入-------||-----(0)退出使用-------||******************************|(3.1)(II)方便快捷的操作:用户只需要根据不同的需要在界面上输入系统提醒的操作形式直接进行相应的操作方式即可!如图(3.2所示)|******************************||-------欢迎使用---------||-----(1)随机取数-------||-----(2)自行输入-------||-----(0)退出使用-------||******************************|请选择操作方式:(用户在此输入操作方式)(3.2)(III)系统采用定义结构体数组来存储数据。
数据结构课程设计题目以下7个题目任选其一。
1.排序算法比较利用随机函数产生30000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并且(1)统计每一种排序上机所花费的时间。
(2)统计在完全正序,完全逆序情况下记录的比较次数和移动次数。
(3)比较的指标为关键字的比较次数和记录的移动次数(一次记录交换计为3次移动)。
(4)对结果作简单分析,包括对各组数据得出结果波动大小的解释。
2.图的深度遍历对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,然后利用堆栈的五种基本运算(清空堆栈、压栈、弹出、取栈顶元素、判栈空)实现图的深度优先搜索遍历。
画出搜索顺序示意图。
3.图的广度遍历对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,然后利用队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)实现图的广度优先搜索遍历。
画出搜索顺序示意图。
4.二叉树的遍历对任意给定的二叉树(顶点数自定)建立它的二叉链表存贮结构,并利用栈的五种基本运算(置空栈、进栈、出栈、取栈顶元素、判栈空)实现二叉树的先序、中序、后序三种遍历,输出三种遍历的结果。
画出搜索顺序示意图。
5.链表操作利用链表的插入运算建立线性链表,然后利用链表的查找、删除、计数、输出等运算反复实现链表的这些操作(插入、删除、查找、计数、输出单独写成函数的形式),并能在屏幕上输出操作前后的结果。
画出搜索顺序示意图。
6.一元稀疏多项式简单计数器(1)输入并建立多项式(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2……cn,en,其中n是多项式的项数,ci,ei分别为第i项的系数和指数。
序列按指数降序排列。
(3)多项式a和b相加,建立多项式a+b,输出相加的多项式。
(4)多项式a和b相减,建立多项式a-b,输出相减的多项式。
用带头结点的单链表存储多项式。
测试数据:(1)(2x+5x8-3.1x11)+(7-5x8+11x9)(2)(6x-3-x+4.4x2-1.2x9)-(-6x-3+5.4x2+7.8x15)(3)(x+x2+x3)+0(4)(x+x3)-(-x-x-3)7.实现两个链表的合并基本功能要求:(1)建立两个链表A和B,链表元素个数分别为m和n个。
数据结构课程设计题⽬《数据结构》课程设计题⽬1. 排序算法的性能分析问题描述设计⼀个测试程序,⽐较⼏种内部排序算法的关键字⽐较次数和移动次数以取得直观感受。
基本要求(1)对冒泡排序、直接排序、选择排序、箱⼦排序、堆排序、快速排序及归并排序算法进⾏⽐较。
(2)待排序表的表长不⼩于100,表中数据随机产⽣,⾄少⽤5组不同数据作⽐较,⽐较指标:关键字参加⽐较次数和关键字的移动次数(关键字交换记为3次移动)。
(3)输出⽐较结果。
选做内容(1)对不同表长进⾏⽐较。
(2)验证各算法的稳定性。
(3)输出界⾯的优化。
2. 排序算法思想的可视化演⽰—1基本要求排序数据随机产⽣,针对随机案例,对冒泡排序、箱⼦排序、堆排序、归并算法,提供排序执⾏过程的动态图形演⽰。
3. 排序算法思想的可视化演⽰—2基本要求排序数据随机产⽣,针对随机案例,,对插⼊排序、选择排序、基数排序、快速排序算法,提供排序执⾏过程的动态图形演⽰。
4. 线性表的实现与分析基本要求①设计并实现线性表。
②线性表分别采取数组(公式化描述)、单链表、双向链表、间接寻址存储⽅式③针对随机产⽣的线性表实例,实现线性表的插⼊、删除、搜索操作动态演⽰(图形演⽰)。
5. 等价类实现及其应⽤问题描述:某⼯⼚有⼀台机器能够执⾏n个任务,任务i的释放时间为r i(是⼀个整数),最后期限为d i(也是整数)。
在该机上完成每个任务都需要⼀个单元的时间。
⼀种可⾏的调度⽅案是为每个任务分配相应的时间段,使得任务i的时间段正好位于释放时间和最后期限之间。
⼀个时间段不允许分配给多个任务。
基本要求:使⽤等价类实现以上机器调度问题。
等价类分别采取两种数据结构实现。
6. ⼀元稀疏多项式计算器问题描述设计⼀个⼀元稀疏多项式简单计算器。
基本要求⼀元稀疏多项式简单计算器的基本功能是:(1)输⼊并建⽴多项式;(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2,…,c n,e n,其中n是多项式的项数,c i,e i,分别是第i项的系数和指数,序列按指数降序排序;(3)多项式a和b相加,建⽴多项式a+b;(4)多项式a和b相减,建⽴多项式a-b;(5)计算多项式在x处的值;(6)计算器的仿真界⾯(选做)7. 长整数的代数计算问题描述应⽤线性数据结构解决长整数的计算问题。
(完整版)数据结构教案1. 引言本教案旨在介绍数据结构的基本概念和常用算法,并提供相应的教学资源和活动设计,以帮助学生掌握数据结构的核心知识和能力。
2. 教学目标- 了解数据结构的概念和作用;- 能够使用常见的数据结构(如链表、栈、队列、树、图等)进行问题建模和解决;- 掌握基本的数据结构算法(如排序、查找、遍历等);- 培养学生的编程能力和解决实际问题的能力。
3. 教学内容3.1 数据结构基础- 数据结构的定义和分类;- 数组和链表的比较与应用;- 栈和队列的概念及应用;- 树的基本概念和遍历方法;- 图的基本概念和遍历方法。
3.2 数据结构算法- 排序算法:插入排序、选择排序、冒泡排序、快速排序、归并排序;- 查找算法:顺序查找、二分查找;- 图的最短路径算法:Dijkstra算法、Floyd算法。
4. 教学方法- 讲授理论知识:通过讲解、示意图和实例等形式,向学生介绍数据结构的基本概念和算法;- 编程实践:让学生通过编写程序来实现常见的数据结构和算法,并解决相关问题;- 组织小组讨论和实践活动:让学生合作完成数据结构相关的实际案例分析和解决方案设计。
5. 教学评估为了评价学生的研究效果和能力,我们将采用以下评估方式:- 课堂作业:包括理论题和编程题,用于检查学生对数据结构的理解和应用能力;- 项目实践:学生需要独立或小组完成一个数据结构相关的实际项目,并进行展示和报告;- 期末考试:综合测试学生对数据结构知识的掌握情况。
6. 教学资源为了辅助教学和学生的研究,我们准备了以下教学资源:- 教材:精选的数据结构教材,供学生进行参考和深入研究;- 幻灯片:用于课堂讲解和学生研究的幻灯片,清晰呈现数据结构的概念和算法;- 编程实践指导:提供编程实践的指导和示例代码,帮助学生快速上手;- 练题和答案:提供大量的练题和详细答案,供学生巩固理论知识和算法思维。
7. 教学活动设计为了培养学生的研究兴趣和主动性,我们将设计以下教学活动:- 小组讨论:学生分组进行数据结构相关的主题讨论,分享思路和解决方案;- 编程比赛:组织学生参加数据结构编程比赛,以提高他们的编程能力和算法思维;- 实例分析:选取经典的数据结构实例,引导学生进行分析和实现,加深对数据结构的理解;- 视频讲解:录制有关数据结构的视频讲解,在线平台上供学生随时观看和研究。
头歌数据结构十大经典排序算法导言在计算机科学中,排序算法是一类常见且重要的算法。
通过对一组元素进行排序,我们可以提高数据的组织性和检索效率。
本文将介绍头歌数据结构十大经典排序算法,包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序和基数排序。
冒泡排序冒泡排序是一种简单直观的排序算法。
它通过多次比较和交换相邻元素的方式,将较大(或较小)的元素逐渐交换至数组的一端,从而达到排序的目的。
选择排序选择排序是一种简单且高效的排序算法。
它通过每次选择未排序部分的最小元素,并将其交换至已排序部分的末尾,从而逐步构建有序序列。
插入排序插入排序是一种自然而然的排序算法。
它通过将待排序元素逐个插入已排序序列的正确位置,不断扩大已排序部分的范围,从而完成排序。
希尔排序希尔排序是一种高效的插入式排序算法。
它通过将待排序元素分组,分组内进行插入排序,然后逐步减小分组的大小,以达到整体有序的目的。
归并排序归并排序是一种高效且稳定的排序算法。
它将已排序的子序列合并,不断递归地执行该操作,直到合并整个序列,从而实现排序。
快速排序快速排序是一种高效的分治排序算法。
它通过选择一个基准元素,将序列分割成两部分,并分别对这两部分进行排序,最终将序列有序地整合起来。
堆排序堆排序是一种高效且稳定的排序算法。
它利用堆这种特殊的数据结构,在每次构建堆过程中,获取最大(或最小)元素,并将其放入已排序部分的末尾,从而完成排序。
计数排序计数排序是一种非比较性的排序算法。
它通过统计每个元素出现的次数,计算每个元素应该在有序序列中的位置,从而完成排序。
桶排序桶排序是一种高效的排序算法。
它通过将元素分配到不同的桶中,并对每个桶进行排序,从而得到排序结果。
基数排序基数排序是一种高效的排序算法。
它通过将待排序元素按照个位、十位、百位等进行排序,最终得到有序序列。
结语头歌数据结构十大经典排序算法是计算机科学中不可或缺的内容。
《数据结构》课程设计报告专业班级姓名学号指导教师起止时间课程设计:排序综合一、任务描述利用随机函数产生n个随机整数(20000以上),对这些数进行多种方法进行排序。
(1)至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。
并把排序后的结果保存在不同的文件中。
(2)统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。
要求:根据以上任务说明,设计程序完成功能。
二、问题分析1、功能分析分析设计课题的要求,要求编程实现以下功能:(1)随机生成N个整数,存放到线性表中;(2)起泡排序并计算所需时间;(3)简单选择排序并计算时间;(4)希尔排序并计算时间;(5)直接插入排序并计算所需时间;(6)时间效率比较。
2、数据对象分析存储数据的线性表应为顺序存储。
三、数据结构设计使用顺序表实现,有关定义如下:typedef int Status;typedef int KeyType ; //设排序码为整型量typedef int InfoType;typedef struct { //定义被排序记录结构类型KeyType key ; //排序码I nfoType otherinfo; //其它数据项} RedType ;typedef struct {RedType * r; //存储带排序记录的顺序表//r[0]作哨兵或缓冲区int length ; //顺序表的长度} SqList ; //定义顺序表类型四、功能设计(一)主控菜单设计为实现通各种排序的功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
程序运行后,给出5个菜单项的内容和输入提示,如下:1.起泡排序2.简单选择排序3.希尔排序4. 直接插入排序0. 退出系统(二)程序模块结构由课题要求可将程序划分为以下几个模块(即实现程序功能所需的函数):●主控菜单项选择函数menu()●创建排序表函数InitList_Sq()●起泡排序函数Bubble_sort()●简单选择排序函数SelectSort()●希尔排序函数ShellSort();●对顺序表L进行直接插入排序函数Insertsort()(三)函数调用关系程序的主要结构(函数调用关系)如下图所示。
数据结构之——⼋⼤排序算法排序算法⼩汇总 冒泡排序⼀般将前⾯作为有序区(初始⽆元素),后⾯作为⽆序区(初始元素都在⽆序区⾥),在遍历过程中把当前⽆序区最⼩的数像泡泡⼀样,让其往上飘,然后在⽆序区继续执⾏此操作,直到⽆序区不再有元素。
这块是对⽼式冒泡排序的⼀种优化,因为当某次冒泡结束后,可能数组已经变得有序,继续进⾏冒泡排序会增加很多⽆⽤的⽐较次数,提⾼时间复杂度。
所以我们增加了⼀个标识变量flag,将其初始化为1,外层循环还是和⽼式的⼀样从0到末尾,内存循环我们改为从最后⾯向前⾯i(外层循环所处的位置)处遍历找最⼩的,如果在内存没有出现交换,说明⽆序区的元素已经变得有序,所以不需要交换,即整个数组已经变得有序。
(感谢@站在远处看童年在评论区的指正)#include<iostream>using namespace std;void sort(int k[] ,int n){int flag = 1;int temp;for(int i = 0; i < n-1 && flag; i++){flag = 0;for(int j = n-1; j > i; j--){/*下⾯这⾥和i没关系,注意看这块,从下往上travel,两两⽐较,如果不合适就调换,如果上来后⼀次都没调换,说明下⾯已经按顺序拍好了,上⾯也是按顺序排好的,所以完美!*/if(k[j-1] > k[j]){temp = k[j-1];k[j-1] = k[j];k[j] = temp;flag = 1;}}}}int main(){int k[3] = {0,9,6};sort(k,3);for(int i =0; i < 3; i++)printf("%d ",k[i]);}快速排序(Quicksort),基于分治算法思想,是对冒泡排序的⼀种改进。
快速排序由C. A. R. Hoare在1960年提出。
排序算法:(1) 直接插入排序 (2) 折半插入排序(3) 冒泡排序 (4) 简单选择排序 (5) 快速排序(6) 堆排序 (7) 归并排序【算法分析】(1)直接插入排序;它是一种最简单的排序方法,它的基本操作是将一个记录插入到已排好的序的有序表中,从而得到一个新的、记录数增加1的有序表。
(2)折半插入排序:插入排序的基本操作是在一个有序表中进行查找和插入,我们知道这个查找操作可以利用折半查找来实现,由此进行的插入排序称之为折半插入排序。
折半插入排序所需附加存储空间和直接插入相同,从时间上比较,折半插入排序仅减少了关键字间的比较次数,而记录的移动次数不变。
(3)冒泡排序:比较相邻关键字,若为逆序(非递增),则交换,最终将最大的记录放到最后一个记录的位置上,此为第一趟冒泡排序;对前n-1记录重复上操作,确定倒数第二个位置记录;……以此类推,直至的到一个递增的表。
(4)简单选择排序:通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换之。
(5)快速排序:它是对冒泡排序的一种改进,基本思想是,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
(6)堆排序: 使记录序列按关键字非递减有序排列,在堆排序的算法中先建一个“大顶堆”,即先选得一个关键字为最大的记录并与序列中最后一个记录交换,然后对序列中前n-1记录进行筛选,重新将它调整为一个“大顶堆”,如此反复直至排序结束。
(7)归并排序:归并的含义是将两个或两个以上的有序表组合成一个新的有序表。
假设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序称为2-路归并排序。
课程设计报告数据结构课程设计题目:各种排序*******专业:网络工程班级:10211302学号:**********指导教师:姜林王志波2012年6 月27 日目录排序算法比较一、程序要求分析二、程序主要功能三、程序运行平台四、程序数据结构五、算法及时间复杂度六、程序源代码七、自我总结各种排序一、需求分析任务:用程序实现插入法排序、起泡法、选择法、快速法、合并法排序;输入的数据形式为任何一个正整数,大小不限。
输出的形式:数字大小逐个递增的数列。
要求给出多组不同元素个数的输入数据,并用列表打印出每种排序下的各趟排序结果。
每个排序法结束时应打印出其元素比较的次数和交换的次数。
此程序需将结果用列表打印,一定要将其打印结果排列好。
二、程序的主要功能1.用户输入任意个数,产生相应数量的随机数2.用户可以自己选择排序方式(直接插入排序,冒泡排序、快速排序、选择排序、二路归并排序五种排序方法)的一种3.程序给出原始数据、排序后从小到大的数据,并给出排序所用的时间,比较的总次数和交换的总次数。
三、程序运行平台Visual C++ 6.0版本四、数据结构1.类:NuovSort{public:void Myface();void choose();void insertsort(int R[],int n); //直接插入排序法void Bubblesort(int R[],int n); //冒泡排序算法实现void quicksort(int R[],int left,int right); //快速排序算法实现void selectsort(int R[],int n); //直接选择排序算法实现void merge(int R[],int A[],int s,int m,int t);//二路归并排序算法实现void mergepass(int R[],int A[],int n,int c);void mergesort(int R[],int n);};2.主界面:Myface() //界面{cout<<"\t -->各种排序算法实现<--"<<endl;cout<<"#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#"<<endl;cout<<"# 1.直接插入排序#"<<endl;cout<<"# 2.冒泡排序#"<<endl;cout<<"# 3.快速排序#"<<endl;cout<<"# 4.直接选择排序#"<<endl;cout<<"# 5.二路归并排序#"<<endl;cout<<"#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#"<<endl;cout<<"enter your choose:";}3.选择界面:choose(){int i,x,n,s,t;time_t t1,t2;double tt1,tt2,tt3,tt4,tt5;cout<<"\t\t\t 欢迎您使用高扬的排序程序"<<endl;cout<<"请问,需要几个被排序数字?"<<endl;do{cout<<"请输入个数(范围在1~500 之间): ";cin>>n;}while((n<1)||(n>500));int left=0,right=n-1;for(i=0;i<n;i++)R[i]=rand()%888+1; //产生随机数cout<<"被排序的数字随机产生如下:"<<endl;for(i=0;i<n;i++)cout<<R[i]<<" ";cout<<endl;cout<<endl;Myface();int m=0;cin>>m;switch(m){case 1:t1=time(NULL);insertsort(R,n);t2=time(NULL);tt1=difftime(t2,t1);cout<<"排序所需时间为:"<<tt1<<endl;break; //直接插入排序算法实现case 2:t1=time(NULL);Bubblesort(R,n);t2=time(NULL);tt2=difftime(t2,t1);cout<<"排序所需时间为:"<<tt2<<endl;break; //冒泡排序算法实现case 3:t1=time(NULL);cout<<"Before the sort,your answer is:";for(x=0;x<n;x++){cout.width(4);cout<<R[x]<<" ";}cout<<endl;quicksort(R,left,right);cout<<"排序的结果是:";for(x=0;x<n;x++)cout<<R[x]<<" ";cout<<endl;cout<<endl;cout<<"元素比较次数为"<<comN3<<"次"<<endl;cout<<"元素交换次数为"<<chaN3<<"次"<<endl;t2=time(NULL);tt3=difftime(t2,t1);cout<<"排序所需时间为:"<<tt3<<endl;break; //快速排序算法实现case 4:t1=time(NULL);selectsort(R,n);t2=time(NULL);tt4=difftime(t2,t1);cout<<"排序所需时间为:"<<tt4<<endl;break; //直接选择排序算法实现case 5:t1=time(NULL);mergesort(R,n);cout<<endl;cout<<"元素比较次数为"<<comN5<<"次"<<endl;cout<<"元素交换次数为"<<chaN5<<"次"<<endl;t2=time(NULL);tt5=difftime(t2,t1);cout<<"排序所需时间为:"<<tt5<<endl;break; //二路归并排序算法实现default:cout<<"input error "<<endl;choose();}}五、算法及时间复杂度(一)各个排序的算法思想:(1)直接插入排序算法思想:将一个记录插入到已排好的有序表中,从而得到一个新的,记录数增加1的有序表。
(2)起泡排序算法思想:首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换,然后比较第二个记录和第三个记录的关键字。
依此类推,直到第N-1和第N个记录的关键字进行过比较为止。
上述为第一趟排序,其结果使得关键字的最大纪录被安排到最后一个记录的位置上。
然后进行第二趟起泡排序,对前N-1个记录进行同样操作。
一共要进行N-1趟起泡排序。
(3)快速排序算法思想:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序。
(4)选择排序算法思想:通过N-I次关键字间的比较,从N-I+1个记录中选出关键字最小的记录,并和第I(1<=I<=N)个记录交换。
(5)二路归并排序算法思想:先将每个数确定为一个空间,然后两两比较,把排序后的结果放在新数组中,然后再两两比较,以此类推,最终把所有的子区间合并为一个区间。
(二)时间复杂度分析六、程序源代码/**********************************************************************************************设计要求:利用随机函数产生N个随机整数(N = 1到500),利用直接插入排序,冒泡排序、快速排序、选择排序、二路归并排序五种排序方法(可添加其它排序方法)进行排序(结果为由小到大的顺序),并统计每一种排序所耗费的时间,比较的总次数和交换的总次数。
#include<ctime>#include<math.h>#include<stdlib.h>#include<iostream>#include<time.h>using namespace std;const int maxsize=500;int R[maxsize];int A[maxsize];int i,n,right,left;int comN1=0,chaN1=0; //直接插入排序中元素比较的次数和交换的次数int comN2=0,chaN2=0; //冒泡排序中元素比较的次数和交换的次数int comN3=0,chaN3=0; //快速排序中元素比较的次数和交换的次数int comN4=0,chaN4=0; //直接选择排序中元素比较的次数和交换的次数int comN5=0,chaN5=0; //合并排序中元素比较的次数和交换的次数class NuovSort{public:void Myface();void choose();void insertsort(int R[],int n); //直接插入排序法void Bubblesort(int R[],int n); //冒泡排序算法实现void quicksort(int R[],int left,int right); //快速排序算法实现void selectsort(int R[],int n); //直接选择排序算法实现void merge(int R[],int A[],int s,int m,int t);//二路归并排序算法实现void mergepass(int R[],int A[],int n,int c);void mergesort(int R[],int n);};void NuovSort::Myface() //界面{cout<<"\t -->各种排序算法实现<--"<<endl;cout<<"#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#"<<endl;cout<<"# 1.直接插入排序#"<<endl;cout<<"# 2.冒泡排序#"<<endl;cout<<"# 3.快速排序#"<<endl;cout<<"# 4.直接选择排序#"<<endl;cout<<"# 5.二路归并排序#"<<endl;cout<<"#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#"<<endl;cout<<"enter your choose:";}void Display(int R[], int n){for(int i=0;i<n;i++){cout.width(4);cout<<R[i];}cout<<endl<<endl;}void NuovSort::choose(){int i,x,n,s,t;time_t t1,t2;double tt1,tt2,tt3,tt4,tt5;cout<<"\t\t\t 欢迎您使用高扬的排序程序"<<endl;cout<<"请问,需要几个被排序数字?"<<endl;do{cout<<"请输入个数(范围在1~500 之间): ";cin>>n;}while((n<1)||(n>500));int left=0,right=n-1;for(i=0;i<n;i++)R[i]=rand()%888+1; //产生随机数cout<<"被排序的数字随机产生如下:"<<endl;for(i=0;i<n;i++)cout<<R[i]<<" ";cout<<endl;cout<<endl;Myface();int m=0;cin>>m;switch(m){case 1:t1=time(NULL);insertsort(R,n);t2=time(NULL);tt1=difftime(t2,t1);cout<<"排序所需时间为:"<<tt1<<endl;break; //直接插入排序算法实现case 2:t1=time(NULL);Bubblesort(R,n);t2=time(NULL);tt2=difftime(t2,t1);cout<<"排序所需时间为:"<<tt2<<endl;break; //冒泡排序算法实现case 3:t1=time(NULL);cout<<"Before the sort,your answer is:";for(x=0;x<n;x++){cout.width(4);cout<<R[x]<<" ";}cout<<endl;quicksort(R,left,right);cout<<"排序的结果是:";for(x=0;x<n;x++)cout<<R[x]<<" ";cout<<endl;cout<<endl;cout<<"元素比较次数为"<<comN3<<"次"<<endl;cout<<"元素交换次数为"<<chaN3<<"次"<<endl;t2=time(NULL);tt3=difftime(t2,t1);cout<<"排序所需时间为:"<<tt3<<endl;break; //快速排序算法实现case 4:t1=time(NULL);selectsort(R,n);t2=time(NULL);tt4=difftime(t2,t1);cout<<"排序所需时间为:"<<tt4<<endl;break; //直接选择排序算法实现case 5:t1=time(NULL);mergesort(R,n);cout<<endl;cout<<"元素比较次数为"<<comN5<<"次"<<endl;cout<<"元素交换次数为"<<chaN5<<"次"<<endl;t2=time(NULL);tt5=difftime(t2,t1);cout<<"排序所需时间为:"<<tt5<<endl;break; //二路归并排序算法实现default:cout<<"input error "<<endl;choose();}}//直接插入排序算法实现void NuovSort::insertsort(int R[],int n){int p,x=1;for(int i=1;i<n;i++){int temp=R[i];int j=i-1;while((j>=0)&&(temp<R[j])){comN1++;R[j+1]=R[j];j--;}comN1++;R[j+1]=temp;chaN1++;cout<<"第"<<x++<<"趟被排序的数字如下:"<<endl;for(p=0;p<n;p++){cout.width(4);cout<<R[p]<<" ";}cout<<endl;}cout<<endl;cout<<"元素比较次数为"<<comN1<<"次"<<endl;cout<<"元素交换次数为"<<chaN1<<"次"<<endl;}//冒泡排序算法实现void NuovSort::Bubblesort(int R[],int n){int flag=1;int x=1; //当flag为0时则停止排序for(int i=1;i<n;i++){for(int i=1;i<n;i++){//i表示趟数,最多n-1趟flag=0;for(int j=n-1;j>=i;j--){comN2++;if(R[j]<R[j-1]){//发生逆序int t=R[j];R[j]=R[j-1];R[j-1]=t;flag=1;//交换,并标记发生了变化chaN2++;}}cout<<"第"<<x++<<"趟被排序的数字如下:"<<endl;for(i=0;i<n;i++){cout.width(4);cout<<R[i];}cout<<endl;}if(flag==0)break;}cout<<endl;cout<<"元素比较次数为"<<comN2<<"次"<<endl;cout<<"元素交换次数为"<<chaN2<<"次"<<endl;}//快速排序算法实现void NuovSort::quicksort(int R[],int left,int right) {int k=left,j=right;int n=right;int t,temp=R[k];while(k<j){while((R[j]>temp)&&(j>k)){comN3++;j--;}if(k<j){t=R[k];R[k]=R[j];R[j]=t;chaN3++;k++;}while((R[k]<temp)&&(k<j)){comN3++;k++;}if(k<j){t=R[k];R[k]=R[j];R[j]=t;chaN3++;j--;}}//一次划分得到基准值的正确位置R[k]=temp;if(left<k-1)quicksort(R,left,k-1);if(k+1<right)quicksort(R,k+1,right);}//直接选择排序算法实现void NuovSort::selectsort(int R[],int n){int i,j,m,p;int t;for(i=0;i<n-1;i++){m=i;for(j=i+1;j<n;j++)if(R[j]<R[m]){comN4++;m=j;}if(m!=i){t=R[i];R[i]=R[m];R[m]=t;chaN4++;}cout<<"第"<<i+1<<"趟被排序的数字如下:"<<endl;for(p=0;p<n;p++){cout.width(4);cout<<R[p]<<" ";}cout<<endl;}cout<<endl;cout<<"元素比较次数为"<<comN4<<"次"<<endl;cout<<"元素交换次数为"<<chaN4<<"次"<<endl;}//二路归并排序算法实现void NuovSort::merge(int R[],int A[],int s,int m,int t)//将两个子区间R[s]~R[m]和R[m+1]~R[t]合并,结果存储在A中{int i,j,temp;i=s;j=m+1;while((i<=m)&&(j<=t)){comN5++;if(R[i]>=R[j]){chaN5++;temp=R[j];for(int k=j-1;k>=i;k--){R[k+1]=R[k];}R[i]=temp;j++;}else{i++;}}for(int l=s;l<=t;l++)A[l]=R[l];}void NuovSort::mergepass(int R[],int A[],int n,int c)//对R数组做一趟排序归并,结果存入A数组中,n为元素个数,c为区间长度{int i,j;i=0;while(i+2*c-1<=n-1)//长度均为c的两个区间合并成一个区间{merge(R,A,i,i+c-1,i+2*c-1);i+=2*c;}if(i+c-1<n) //长度不等的两个区间合并成一个区间merge(R,A,i,i+c-1,n-1);else //仅剩一个区间时直接复制到A中for(j=i;j<=n-1;j++)A[j]=R[j];}void NuovSort::mergesort(int R[],int n){int c=1,i=0,k=1;int A[maxsize];cout<<"二路归并排序的每一次的结果如下:"<<endl<<endl;cout<<"初始状态:";Display(R,n);while(c<n){mergepass(R,A,n,c); //一次合并且结果存入A中i=i+1;cout<<"第"<<k<<"趟: ";k++;Display(R,n);c*=2;mergepass(A,R,n,c); //再次合并且结果存入R中i=i+1;cout<<"第"<<k<<"趟: ";k++;Display(R,n);c*=2;}}//函数的实现int main(){NuovSort v;char ch;cout<<"\t\t\t -->各种排序算法实现<--"<<endl;do{v.choose();cout<<endl;cout<<"\t\t\t --> 继续操作按'Y;,退出按'N' <-"<<endl;cin>>ch;while(ch!='Y'&&ch!='N'){cout<<"请根据提示操作!## 继续操作按'Y;,退出按'N' ##"<<endl;cin>>ch;}}while(ch!='N');return 0;}七、自我总结经过三天的努力,终于做完了这份程序。