排序算法的比较
排序算法比较

排序算法比较
排序算法的效率主要取决于算法的时间复杂度。
以下是常见的几种排序算法的时间复杂度和优缺点的对比:
1. 冒泡排序
冒泡排序的时间复杂度为O(n^2)。
优点是它的实现简单易懂,缺点是排序速度很慢,对大规模数据排序不太适用。
2. 插入排序
插入排序的时间复杂度也为 O(n^2)。
它的优点是适用于小数
据量的排序,缺点是对于大规模数据排序仍然效率不高。
3. 选择排序
选择排序的时间复杂度也为 O(n^2)。
它的优点是对于小数据
量的排序速度较快,但是因为其算法结构固定,所以其效率在大规模数据排序中表现不佳。
4. 快速排序
快速排序的时间复杂度为 O(nlogn)。
它是一种非常常用的排序算法,适用于大规模数据排序。
快速排序的优点在于分治的思想,可以充分发挥多线程并行计算的优势,缺点是在极端情况下(如输入的数据已经有序或者逆序)排序速度会较慢。
5. 堆排序
堆排序的时间复杂度为 O(nlogn)。
它的优点在于实现简单、稳定,可以用于实时系统中的排序。
缺点是在排序过程中需要使用一个堆结构来维护排序序列,需要额外的内存开销。
同时,由于堆的性质,堆排序不能发挥多线程并行计算的优势。
6. 归并排序
归并排序的时间复杂度为 O(nlogn)。
它的优点在于稳定、可靠,效率在大规模数据排序中表现良好。
归并排序在实现过程中需要使用递归调用,需要额外的内存开销。
同时,归并排序不适用于链式存储结构。
算法实验报告

算法实验报告算法实验报告引言:算法是计算机科学的核心内容之一,它是解决问题的方法和步骤的描述。
算法的设计和分析是计算机科学与工程中的重要研究方向之一。
本实验旨在通过对算法的实际应用和实验验证,深入理解算法的性能和效果。
实验一:排序算法的比较在本实验中,我们将比较三种常见的排序算法:冒泡排序、插入排序和快速排序。
我们将通过对不同规模的随机数组进行排序,并记录每种算法所需的时间和比较次数,以评估它们的性能。
实验结果显示,快速排序是最快的排序算法,其时间复杂度为O(nlogn),比较次数也相对较少。
插入排序的时间复杂度为O(n^2),比较次数较多,但对于小规模的数组排序效果较好。
而冒泡排序的时间复杂度也为O(n^2),但比较次数更多,效率相对较低。
实验二:图的最短路径算法在图的最短路径问题中,我们将比较Dijkstra算法和Floyd-Warshall算法的效率和准确性。
我们将使用一个带权有向图,并计算从一个顶点到其他所有顶点的最短路径。
实验结果表明,Dijkstra算法适用于单源最短路径问题,其时间复杂度为O(V^2),其中V为顶点数。
而Floyd-Warshall算法适用于多源最短路径问题,其时间复杂度为O(V^3)。
两种算法在准确性上没有明显差异,但在处理大规模图时,Floyd-Warshall算法的效率较低。
实验三:动态规划算法动态规划是一种通过将问题分解成子问题并记录子问题的解来解决复杂问题的方法。
在本实验中,我们将比较两种动态规划算法:0-1背包问题和最长公共子序列问题。
实验结果显示,0-1背包问题的动态规划算法可以有效地找到最优解,其时间复杂度为O(nW),其中n为物品个数,W为背包容量。
最长公共子序列问题的动态规划算法可以找到两个序列的最长公共子序列,其时间复杂度为O(mn),其中m和n分别为两个序列的长度。
结论:通过本次实验,我们对不同算法的性能和效果有了更深入的了解。
排序算法中,快速排序是最快且效率最高的;在图的最短路径问题中,Dijkstra算法和Floyd-Warshall算法分别适用于不同的场景;动态规划算法可以解决复杂的问题,并找到最优解。
常用排序算法分析比较

常用排序算法分析比较排序算法是计算机科学中的基本概念之一,它主要用于对一组元素进行排序,使得这些元素按照某种规则有序排列。
常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序、归并排序等等,这些算法都有自己的特点和适用场景,下面针对这些排序算法进行分析比较。
1.冒泡排序冒泡排序是一种简单的排序算法,它的主要思想是依次比较相邻的两个元素,如果它们的顺序不对就交换它们的位置,可以保证每次循环后最后一个元素是已经排序好的。
冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。
2.插入排序插入排序是一种稳定的排序算法,它的基本思想是将待排序的数据分为两个区间,已排序区间和未排序区间,在未排序区间内遍历,将每个元素插入到已排序区间的合适位置。
插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。
3.选择排序选择排序是一种比较简单的排序算法,它的主要思想是通过不断选择未排序区间内的最小值,然后和未排序区间的第一个元素交换位置,以此类推,直到排序完毕。
选择排序的时间复杂度为O(n^2),空间复杂度为O(1)。
4.快速排序快速排序是一种经典的排序算法,它的思想是采用分治的思想,将序列分为左右两个子序列,通过递归的方式对左右两个子序列进行快速排序,最后合并两个排好序的子序列。
快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn)。
5.归并排序归并排序是一种稳定的排序算法,它的基本思想是采用分治的思想,将序列分为左右两个子序列,通过递归的方式对左右两个子序列进行排序,最后将两个排好序的子序列合并成一个有序序列。
归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。
通过比较以上五种排序算法,可以发现每种算法都有自己的特点和适用场景,对于元素数量较少的情况下,可以选择冒泡排序、插入排序或选择排序,这些算法思路简单易懂,实现也比较容易;对于大规模数据排序,可以选择归并排序或快速排序,因为它们的时间复杂度比较优秀。
各种排序算法的总结和比较

各种排序算法的总结和比较1 快速排序(QuickSort )快速排序是一个就地排序,分而治之,大规模递归的算法。
从本质上来说,它是归并排序的就地版本。
快速排序可以由下面四步组成。
(1 )如果不多于1 个数据,直接返回。
(2 )一般选择序列最左边的值作为支点数据。
(3 )将序列分成2 部分,一部分都大于支点数据,另外一部分都小于支点数据。
(4 )对两边利用递归排序数列。
快速排序比大部分排序算法都要快。
尽管我们可以在某些特殊的情况下写出比快速排序快的算法,但是就通常情况而言,没有比它更快的了。
快速排序是递归的,对于内存非常有限的机器来说,它不是一个好的选择。
2 归并排序(MergeSort )归并排序先分解要排序的序列,从1 分成2 ,2 分成4 ,依次分解,当分解到只有1 个一组的时候,就可以排序这些分组,然后依次合并回原来的序列中,这样就可以排序所有数据。
合并排序比堆排序稍微快一点,但是需要比堆排序多一倍的内存空间,因为它需要一个额外的数组。
3 堆排序( HeapSort )堆排序适合于数据量非常大的场合(百万数据)。
堆排序不需要大量的递归或者多维的暂存数组。
这对于数据量非常巨大的序列是合适的。
比如超过数百万条记录,因为快速排序,归并排序都使用递归来设计算法,在数据量非常大的时候,可能会发生堆栈溢出错误。
堆排序会将所有的数据建成一个堆,最大的数据在堆顶,然后将堆顶数据和序列的最后一个数据交换。
接下来再次重建堆,交换数据,依次下去,就可以排序所有的数据。
4 Shell 排序( ShellSort )Shell 排序通过将数据分成不同的组,先对每一组进行排序,然后再对所有的元素进行一次插入排序,以减少数据交换和移动的次数。
平均效率是O(nlogn) 。
其中分组的合理性会对算法产生重要的影响。
现在多用D.E.Knuth 的分组方法。
Shell 排序比冒泡排序快5 倍,比插入排序大致快2 倍。
Shell 排序比起QuickSort ,MergeSort ,HeapSort 慢很多。
基于比较的排序算法的基本操作

比较排序算法是一种重要的排序算法,它通过比较相邻的元素来确定它们的顺序。
在比较排序算法中,有三种基本操作:比较、交换和遍历。
1. 比较:比较排序算法的核心是比较相邻的元素,以确定它们的顺序。
比较操作的实现方式多种多样,但最常见的方法是使用“小于等于”关系进行比较。
例如,如果要将数组[2, 4, 1, 3, 5, 7]排序,首先比较第一个元素和第二个元素,即2和4,由于2小于4,将它们交换,即2和4互换位置,得到数组[4, 2, 1, 3, 5, 7]。
然后,比较第二个元素和第三个元素,即4和1,由于4大于1,不进行交换,即数组[4, 2, 1, 3, 5, 7]。
接着,比较第三个元素和第四个元素,即1和3,由于1小于3,将它们交换,即1和3互换位置,得到数组[4, 3, 1, 2, 5, 7]。
然后,比较第四个元素和第五个元素,即3和2,由于3大于2,不进行交换,即数组[4, 3, 1, 2, 5, 7]。
接着,比较第五个元素和第六个元素,即2和5,由于2小于5,将它们交换,即2和5互换位置,得到数组[4, 3, 2, 5, 1, 7]。
最后,比较第六个元素和第七个元素,即5和7,由于5大于7,不进行交换,即数组[4, 3, 2, 5, 1, 7]。
2. 交换:当两个元素之间的比较结果为“小于等于”关系时,需要将它们交换位置。
交换操作是比较排序算法中最基本的操作之一,它将一个元素从一个位置移动到另一个位置。
在实现交换操作时,需要使用一个临时变量来存储要交换的元素。
例如,如果要将数组[2, 4, 1, 3, 5, 7]排序,第一次比较后得到数组[4, 2, 1, 3, 5, 7],交换操作将1和3交换位置,得到数组[4, 3, 1, 2, 5, 7]。
3. 遍历:比较排序算法需要遍历整个数组,以确定每个元素的位置。
遍历操作是比较排序算法中最基本的操作之一,它通过依次比较每个元素和它的后继元素来确定每个元素的位置。
排序算法比较

一.排序算法比较1.问题描述对直接插入排序,直接选择排序,冒泡排序,快速排序,堆排序五种排序算法进行比较.要求: 1.被排序的对象由计算机随机生成,分别取长度为500,20000,10000002.算法中增加比较移动次数和比较次数的统计功能,并统计在排序同一组随机数时每种排序算法的运行时间,及占用内存情况.3.对实验的结果进行比较2.设计思路这是一个算法性能评价程序,重点在于算法性能的评价上.实现某一功能可能有很多方法,判断一个算法好坏的标准主要有时间复杂度和空间复杂度.在当今系统资源相对充足的计算机系统中,时间复杂度变成了头等问题.对于每一个排序算法都应该有两个返回值:比较次数和移动次数.但在C语言中只能有一个函数返回值,故这里采用指针传递地址的方式通过形参的地址从而可以修改实参值.这样一来,在每个排序算法参数列表中,除了含被排序指针对象外,另外加两个整型变量指针,用于传递算法执行过程中的比较次数和移动次数.取一定长度的对象,由计算机产生一定量的伪随机数后,主函数,调用各个排序函数,但由于排序对象也是指向一维数组的指针,在调用一次排序算法后,通过形参对指针的改变,被排序对象已经是有序的了.当再一次用其他排序算法后,有可能比较次数和移动次数达到最大或最小.无论是哪种情况都是不好的,这样一来,就失去了算法复杂度的比较意义了.为了避免这种情况的出现本程序采用在排序前新建一个数组,将保存随机数的数组复制到该数组,让排序算法对该数组进行排序.这样就不会改变原始对象的随机性.在统计排序算法运行时间时采用新建两个time_t对象,排序开始前接收一次系统时间,排序结束后接收一次系统时间,二者的差值即为排序算法所运行的时间。
3.数据结构设计本程序中考虑的内容是排序对象,排序的依据是关键字之间的大小比较。
故在每个节点类型定义中,至少得包含关键字key这一项。
被排序对象由一个个节点构成,一个排序对象包含一系列指向一串节点的指针,指针对象长度。
数字的大小比较及排序方法

数字的大小比较及排序方法在数学和计算机领域,比较和排序是常见的操作。
当我们面对一系列数字时,我们需要进行比较以确定数字的大小关系,然后可能需要将它们按照一定的顺序进行排序。
本文将探讨数字的大小比较方法以及常用的排序算法。
一、数字的大小比较方法在进行数字比较时,我们可以使用以下几种方法:1. 直接比较法:直接比较数字的大小是最简单直接的方法。
例如,当我们比较两个数字a和b时,我们可以使用如下表达式:a >b :表示a大于ba <b :表示a小于ba =b :表示a等于b2. 绝对值比较法:有时我们不仅需要比较数字的大小关系,还需要考虑数字的正负情况。
此时,我们可以使用绝对值进行比较。
例如,当我们比较两个数字a和b的大小时,我们可以比较它们的绝对值 |a| 和 |b|,并按照绝对值的大小关系得出结果。
3. 比较符号法:除了使用比较运算符进行比较外,我们还可以使用比较符号进行数字的大小比较。
常用的比较符号包括“>”(大于)、“<”(小于)、“=”(等于)、“≥”(大于等于)和“≤”(小于等于)。
二、数字的排序方法当我们有一系列数字需要排序时,我们可以使用下列排序算法:1. 冒泡排序法:冒泡排序法是最简单的排序算法之一。
它通过反复比较相邻两个数字的大小,并根据需要交换它们的位置,直到所有数字按照指定的顺序排列。
冒泡排序法的时间复杂度为O(n^2)。
2. 插入排序法:插入排序法通过将数字逐个插入到已排好序的数字序列中,完成排序。
插入排序法的时间复杂度为O(n^2),但在实际应用中经常比其他排序算法更快。
3. 快速排序法:快速排序法是一种分治排序算法。
它通过选择一个枢纽元素,将序列划分为左右两个子序列,并对子序列进行递归排序,最终完成整个序列的排序。
快速排序法的时间复杂度为O(nlogn),但在极端情况下可能达到O(n^2)。
4. 归并排序法:归并排序法也是一种分治排序算法。
它将序列递归地划分为较小的子序列,然后将子序列合并为一个有序序列,直到整个序列有序。
几种排序的算法时间复杂度比较

几种排序的算法时间复杂度比较1.选择排序:不稳定,时间复杂度 O(n^2)选择排序的基本思想是对待排序的记录序列进行n-1遍的处理,第i遍处理是将L[i..n]中最小者与L[i]交换位置。
这样,经过i遍处理之后,前i个记录的位置已经是正确的了。
2.插入排序:稳定,时间复杂度 O(n^2)插入排序的基本思想是,经过i-1遍处理后,L[1..i-1]己排好序。
第i遍处理仅将L[i]插入L[1..i-1]的适当位置,使得L[1..i] 又是排好序的序列。
要达到这个目的,我们可以用顺序比较的方法。
首先比较L[i]和L[i-1],如果L[i-1]≤ L[i],则L[1..i]已排好序,第i遍处理就结束了;否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),使得L[j] ≤L[j+1]时为止。
图1演示了对4个元素进行插入排序的过程,共需要(a),(b),(c)三次插入。
3.冒泡排序:稳定,时间复杂度 O(n^2)冒泡排序方法是最简单的排序方法。
这种方法的基本思想是,将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮。
在冒泡排序算法中我们要对这个“气泡”序列处理若干遍。
所谓一遍处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。
如果发现两个相邻元素的顺序不对,即“轻”的元素在下面,就交换它们的位置。
显然,处理一遍之后,“最轻”的元素就浮到了最高位置;处理二遍之后,“次轻”的元素就浮到了次高位置。
在作第二遍处理时,由于最高位置上的元素已是“最轻”元素,所以不必检查。
一般地,第i遍处理时,不必检查第i高位置以上的元素,因为经过前面i-1遍的处理,它们已正确地排好序。
4.堆排序:不稳定,时间复杂度 O(nlog n)堆排序是一种树形选择排序,在排序过程中,将A[n]看成是完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
排序算法的比较1 课程设计名称 排序算法的比较概述 排序是计算机程序设计中的一种重要操作。
它的功能是将一个数据元素(或 记录)的任意序列,重新排列成一个按关键字有序的序列。
内部排序算法主要分 为5 大类,有十二个算法。
插入排序类、交换排序类、选择排序类、归并排序类 和基数排序类。
算法主要包括:插入排序、折半插入排序、选择排序、冒泡排序、 希尔排序、快速排序、堆排序、归并排序、基数排序等。
2 使用工具软件Microsoft Visual C++ 6.03 课程设计内容简介3.1 课程设计内容掌握各种排序算法(直接插入排序、冒泡排序、快速排序、简单选择排序)的思路核比较他们之间的优劣。
3.2 基本要求1.任意性:系统首先生成 1000 个随机整数,然后分别用不同的排序方法对 其进行升序排序,给出每种方法的比较次数或所用时间 2.友好性:界面要友好,输入有提示,尽量展示人性化 3.可读性:源程序代码清晰、有层次 4.健壮性:用户输入非法数据时,系统要及时给出警告信息3.3 课程设计思想程序设计的总体思路:首先构建 main()函数,根据题目的要求,再分 别构建四个排序函数:冒泡排序函数(long Bubblesort(long R[], long n)) 、 选择排序函数(long selectsort(long R[],long n)) 、直接插入排序函数(long insertsort(long R[], long n) ) 和 快 速 排 序 函 数 ( void QuickSort(long R[],long n) ) 。
为了使程序具有可读性和层次感,建立一个导航函数( void DaoHang()) 和操作函数 (void operate(long a[], long n)) , 其中, void DaoHang() 用来告知用户程序的操作流程,void operate(long a[], long n)用来接收用户 不同的选择,从而调用其它函数。
3.4 程序分析3.4.1 存储结构 顺序存储结构(如图 1) 示意图 a0 a1 a2 图1 3.4.2 关键算法分析 关键算法 1 实现四种算法的基本排序功能 1.冒泡排序:两两比较相邻记录的关键码,如果反序则交换,直到没有反序 记录为止。
实现过程(如图 2) 。
对于数组(21 25 49 16 08) 。
初态: 21 第一趟: 25 49 16 08 a3 a421 第二趟: 21 第三趟: 16 第四趟: 082516084916082549082125491621图225492.选择排序:从待排序的记录序列中选择关键码最小(或最大)的记录并将 它与序列中的第一个记录交换位置; 然后从不包括第一个位置上的记录序列中选 择关键码最小(或最大)的记录并将它与序列中的第二个记录交换位置;如此重 复,直到序列中只剩下一个记录为止。
实现过程(如图 3) 。
对于数组(21 25 49 16 08) 。
初态: 21 第一趟: 08 第二趟: 08 第三趟: 08 16 21图325491608254916211649252125493. 直接插入排序: 依次将待排序的序列中的每一个记录插入到先前排序好的 序列中,直到全部记录排序完毕。
实现过程(如图 4) 。
对于数组(21 25 49 16 08) 。
初态: 21 第一趟: 21 第二趟: 21 25 49 16 08 25 49 16 08 25 49 16 08第三趟: 21 第四趟: 16 第五趟: 08 16 21图4254916082125490825494.快速排序:首先选择一个基准,将记录分割为两部分,左支小于或等于基 准,右支则大于基准,然后对两部分重复上述过程,直至整个序列排序完成。
实现过程(如图 5) 对于数组(21 25 49 16 08) 。
初态: R[0]=21 21 low 第一趟: R[0]=21 08 R[0]=21 08 25 low R[0]=21 08 R[0]=21 08 R[0]=21 08 16 49 49 25 16 49low25491608 high25 low491608 high4916high2516 low491625high16high25R[0]=21 low=high 08 关键算法二 获取当前系统时间,精确到毫秒,分别在代码运行前后调用记录前后时间, 再相减即可得到代码运行时间。
//以冒泡排序为例 start=(double)clock();//开始 Bubblesort(R, n); end=(double)clock();//结束 Time = (double)(end-start)/CLK_TCK;//相减,精确到毫秒 关键算法三: 实现手动与计算机随机双重输入。
手动输入检查程序的正确性,计算机随即 输入,可以比较各排序算法的性能。
void Rand()//随机数函数 void HandInput()//手动输入函数 关键算法四 纠错功能。
在用户输入非法数据时,给予警告,并要求用户重新输入,不必 重启程序。
16low high21图549253.4.3 时间复杂度与空间复杂度: 理论分析可以得出各种排序算法的时间复杂度和空间复杂度,如下表所示 (图6) :排序方法平均情况最好情况最坏情况辅助空间直接插入排序O(n2)O(n)O(n2)O(1)起泡排序O(n2)O (n)O(n2)O(1)快速排序O(nlog2n)O(nlog2n)O(n2)O(log2n) ~O(n)简单选择排序O(n2)O(n2)图6O(n2)O(1)3.4.4 选择排序算法的依据 影响排序的因素有很多, 平均时间复杂度低的算法并不一定就是最优的。
相 反,有时平均时间复杂度高的算法可能更适合某些特殊情况。
同时,选择算法还 得考虑它的可读性, 以利于软件的维护。
一般而言, 需要考虑的因素有以下4 点: 待排序的记录数目n 的大小。
记录本身数据量的大小,也就是记录中除关键字外的其他信息量的 大小。
关键字的结构及其分布情况。
对排序稳定性的要求。
3.5 程序流程图main()输入错误判断手动还是随 机输入(1,2)?2 1HandInput() (手动输入)Rand(); (随机输入)cin>>a[i] ;//数据存储void DaoHang()void operate()输入错误选择排序 方法 输入 0输入 a输入排序方法 结束 Void print()图73.6 运行环境Microsoft Visual C++ 6.0/WIN32 Console Application3.7 运行结果3.7.1 当手动输入五个数据时,运行结果(如图 8)图83.7.2 当选择随机数时,运行结果(如图 9)图93.8 得意之处得意之处 1 将时间精确到毫秒,使得实验结果更容易观察比较。
代码如下(冒泡排序为例) : start=(double)clock(); degree = Bubblesort(R, n);end=(double)clock(); Time = (double)(end-start)/; 其中 CLK_TCK 值为 1000,即将时间精确到毫秒(图 10) 。
图 10得意之处 2 将排序过程的每一趟输出,并且将已排好序的用中括号括起来,这样以来, 可以直接看出排序过程是否正确以及深入了解排序过程的每一步。
如:对于冒泡排序(图 11)图 11得意之处 3 冒泡排序算法中,运用做标记的方法,使得排序得到正确结果后,便停止做 不必要的循环。
代码如下 while(i>1) { long lastExchangeIndex=1;//表示已经有序 for(long j=1;j<i;j++) if(R[j+1]<R[j]) { long t=R[j]; R[j]=R[j+1]; R[j+1]=t; BT++; lastExchangeIndex=j;//记下进行的位置 } i=lastExchangeIndex;//本趟进行过交换的最后一个记录的位置 }4 课程设计中目前存在问题1.交换次数统计不够精确。
2.无论时间还是移动次数,应该有一个对比结果,不能只是罗列出来。
3.对于快速排序,存在两个问题。
其一,不能两边同时进行排序,使得排序趟数增加;其二,没能格式化输出,使得输出不清晰,不美观。
5 自我感受1.在初期构思代码的时候,首先构造了各种算法的基本实现代码,已经能够实现四种排序的基本功能,并且测试无误。
后来考虑能否优化本程序,首先考虑到测试算法的需求,需要大量随机数,因为增添了随机函数发生函数,满足各种测试条件的需求。
之后考虑如何能简化代码以实现多达四种排序算法的简单调用和性能指标统计、算法时间的精确而简易的统计、算法移动次数和比较次数的精确统计。
调用精确的系统函数实现时间的统计。
此外还添加了一系列优化,使得程序的结构变得更加合理,版面风格也变得好看,可读性增强。
2.程序的优化是一个艰辛的过程,如果只是实现一般的功能,将变得容易很多,当加上优化,不论是效率还是结构优化,都需要精心设计。
这次做优化的过程中,遇到不少阻力。
因而以后要多花力气学习C++编程语言,必须要加强这方面的训练,这样才能在将编程思想和数据结构转换为代码的时候能得心应手。
3.这次课设通过在网上查阅大量资料、程序以及一些学术论文,很好的对内排序算法进行了研究,特别对数据结构这门课所学到的内容付诸于实践,加深了理解。
另外,还学到了一写别的方面的知识。
这次课设做还有许多没有考虑周到的地方,希望老师指出。
6参考文献[1] 严蔚敏吴伟民,数据结构(C语言版),北京:清华大学出版社,2007。
[2] 汪祖柱沈晓潞,基于C语言实现的若干排序算法和分析,安徽电气工程职业学院学报,第九卷第一期。
[3] 王莉,常用内部排序算法的比较与选择,软件导刊,2006年1月号。
[4] 赵延惠,排序方法及效率浅析,思茅师范高等专科学校学报,第18卷附录:程序#include <iostream>#include<stdio.h>#include <stdlib.h>#include <time.h>#include <iomanip>#define MAX 100000000using namespace std;void print(long R[],long n){for(int i=1;i<=n;i++)cout<<setw(4)<<R[i];}//------------------------------------------------------------------------------//冒泡排序//------------------------------------------------------------------------------long Bubblesort(long R[], long n){long y=1;long i,BT=0;i=n;while(i>1){long lastExchangeIndex=1;//表示已经有序for(long j=1;j<i;j++)if(R[j+1]<R[j]){long t=R[j];R[j]=R[j+1];R[j+1]=t;BT++;lastExchangeIndex=j;//记下进行的位置}i=lastExchangeIndex;//本趟进行过交换的最后一个记录的位置cout<<"第"<<y<<"趟:";y++;for(long x=1;x<=i;x++)cout<<setw(4)<<R[x];cout<<setw(3)<<"["<<R[i+1];for(x=i+2;x<=n;x++)cout<<setw(4)<<R[x];cout<<"]";cout<<endl;}return BT;}//------------------------------------------------------------------------------//选择排序//------------------------------------------------------------------------------//static long ST=0;long SelectMinKey(long R[],long i,long n)//在R[i..R.length] 中选择关键字最小的记录{long temp=i;//记录最小的元素值的位置for(int j=i;j<=n;j++){if(R[temp]>R[j]){temp=j;//ST++;}}return temp;}long selectsort(long R[],long n){long j,i,t;long y=1;int ST=0;for( i=1;i<n;i++){j = SelectMinKey(R,i,n);// 在L.r[i..L.length] 中选择关键字最小的记录if (i!=j) // 与第i 个记录交换{t=R[i];R[i]=R[j];R[j]=t;ST++;}cout<<"第"<<y<<"趟:"<<' ';y++;for(long x=1;x<=i;x++)cout<<setw(4)<<R[x];cout<<setw(3)<<"["<<R[i+1];for(x=i+2;x<=n;x++)cout<<setw(4)<<R[x];cout<<"]";//print(R,n);cout<<endl;}return ST;}//------------------------------------------------------------------------------ //直接插入排序//------------------------------------------------------------------------------ long insertsort(long R[], long n){long y=1;long IT=0,j;for(long i=2;i<=n;++i){if(R[i]<R[i-1]){R[0]=R[i];//复制为哨兵IT=IT+1;for( j=i-1;R[0]<R[j];--j){R[j+1]=R[j];//记录后移IT=IT+1;}R[j+1]=R[0];//插入到正确位置IT=IT+1;}cout<<"第"<<y<<"趟:"<<' ';y++;cout<<setw(4)<<"["<<R[1];for(long x=2;x<=i;x++)cout<<setw(4)<<R[x];cout<<"]";for(x=i+1;x<=n;x++)cout<<setw(4)<<R[x];cout<<endl;}return IT;}//------------------------------------------------------------------------------ // 快速排序//------------------------------------------------------------------------------ static long QT=0;int Partition (long R[], long low, long high,long n){R[0] =R[low];long pivotkey = R[low]; // 枢轴QT=QT+2;while (low<high){while(low<high&& R[high]>=pivotkey)// 从右向左搜索-- high;R[low] = R[high];QT=QT+1;while (low<high && R[low]<=pivotkey)// 从左向右搜索++ low;R[high] = R[low];}QT=QT+1;R[low] =R[0];QT=QT+1;return low;}// Partitionvoid quicksort (long R[], int low, int high,long n,long y)// 对记录序列L.r[low..high]进行快速排序{if (low < high) // 长度大于1{long pivotloc = Partition(R,low,high,n);// 对L.r[low..high] 进行一次划分QT=QT+1;cout<<"第"<<y<<"趟:";y++;print(R,pivotloc-1);cout<<setw(2)<<"["<<R[pivotloc];cout<<"]";for(long x=pivotloc+1;x<=n;x++)cout<<setw(5)<<R[x];cout<<endl;quicksort(R, low, pivotloc-1,n,y); // 对低子序列递归排序quicksort(R, pivotloc+1, high,n,y); // 对高子序列递归排序}} // QSortvoid QuickSort(long R[],long n){long y=1;quicksort(R,1,n,n,y);}//------------------------------------------------------------------------------ //操作选择函数//------------------------------------------------------------------------------ void operate(long a[], long n){void main();long * R = new long [n];time_t start, end;//定义两个变量double Time;//排序时间long degree;//排序次数char ch;cout << "请选择排序算法:\t";cin >> ch;switch(ch){case '1':{cout<<'\n';cout<<"\t==您选择的是冒泡排序=="<<'\n';for(int i = 1; i <=n; i ++)//将随机数付给R[i]{R[i] = a[i];}start=(double)clock();degree = Bubblesort(R, n);end=(double)clock();Time = (double)(end-start)/CLK_TCK;//print(R,n);cout << '\n';cout << "冒泡排序所用时间:\t" << Time << '\n';cout << "冒泡排序交换次数:\t" << degree << '\n';cout<<'\n';operate(a, n);break;}case '2':{cout<<'\n';cout<<"\t==您选择的是选择排序=="<<'\n';for(int i = 1; i <= n; i ++){R[i] = a[i];}start=(double)clock();degree = selectsort(R, n);end=(double)clock();Time = (double)(end-start)/CLK_TCK;//print(R,n);cout<<'\n';cout << "选择排序所用时间:\t" << Time << '\n';cout << "选择排序交换次数:\t" << degree << '\n';cout << '\n';operate(a, n);break;}case '3':{cout<<'\n';cout<<"\t==您选择的是直接插入排序=="<<'\n';for(int i=1; i<=n; i ++){R[i] = a[i];}start=(double)clock();degree = insertsort(R, n);end=(double)clock();Time = (double)(end-start)/CLK_TCK;//print(R,n);cout<<'\n';cout << "直接插入排序所用时间:" << Time<< '\n';cout << "直接插入排序交换次数:" << degree << '\n';cout << '\n';operate(a, n);break;}case '4':{cout<<'\n';cout<<"\t==您选择的是快速排序=="<<'\n';for(int i=1; i<=n; i ++){R[i] = a[i];}start=(double)clock();QuickSort(R, n);end=(double)clock();Time = (double)(end-start)/CLK_TCK;cout<<'\n';cout << "快速排序所用时间:\t" << Time << '\n';cout << "快速排序交换次数:\t" << QT << '\n';cout << '\n';operate(a, n);break;}case 'a':{main();break;}default:{cout << "输入错误,请选择正确的操作!" << '\n';operate(a, n);break;}case '0':{cout<<"您已选择退出程序,谢谢使用"<<'\n';break;}}}//------------------------------------------------------------------------------//导航菜单函数//------------------------------------------------------------------------------void DaoHang(){cout<<"\n** 排序算法比较**"<<endl;cout<<"*****************************************************"<<endl;cout<<"== 1 --- 冒泡排序=="<<endl;cout<<"== 2 --- 选择排序=="<<endl;cout<<"== 3 --- 直接插入排序=="<<endl;cout<<"== 4 --- 快速排序=="<<endl;cout<<"== 0 --- 退出程序cout<<"== a --- 改变随机数的个数=="<<endl; cout<<"*****************************************************"<<endl; }//--------------------------------------------------------------------------------//随机输入函数//--------------------------------------------------------------------------------void Rand(){cout << "\n请输入要产生的随机数的个数(0<=n<=100000000):"<<endl;long int n;cin >> n;cout << endl;long *a = new long [n];srand((unsigned long)time(NULL));//产生一个以当前时间开始的随机种子for (long i=1; i<=n; i++){a[i] = rand() % n;//n为最大值,其随机域为0~n-1}DaoHang();print(a,n);operate(a, n);}//--------------------------------------------------------------------------------//手动输入函数//--------------------------------------------------------------------------------void HandInput(){cout<<"请输入数据个数:"<<endl;int n;cout<<"n=";cin>>n;cout << endl;long *a = new long [n];for (long i=1; i<=n; i++){cin>>a[i] ;}DaoHang();operate(a, n);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------ void main(){loop:cout<<"手动输入请按1 ,随机输入请按2 "<<endl;int x;cin>>x;switch(x){case 2:{Rand();break;}case 1:{HandInput();break;}default:cout<<"输入错误,请重新输入!"<<endl;goto loop;}}。