《数据结构》课程设计报告---排序算法的实现与比较

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

《数据结构》课程设计报告

排序算法的实现与比较

设计内容及要求

编程实现插入、希尔、快速、堆排序、归并排序算法,并计算每种算法的比较、交换次数。将

待排数据从磁盘文件读入,实施排序后将数据写入另一个文件中。

概述

在本设计课题中,我们将对常见的5中排序算法——插入、希尔、快速、堆排序、归并排

序进行各种情况下的比较,如待排数据为顺序、逆序或随机的情况下,各个算法对于特定数据

的性能。基于此点考虑,在程序中选择采用以毫秒为单位的执行时间来衡量算法对特定数据的

性能高低。本文将主要介绍《排序之谜》程序(以下简称“程序”)的数据结构的设计、功能

设计以及相关技术讨论等。本程序在Microsoft Windows Server 2003/Microsoft Visual C++ 2005的命令行编译器cl.exe环境编译下通过。

分发包说明

程序分发包中将包含以下文件,其用途分别如表格1所示。

数据结构设计

主程序数据结构

主程序中采用两个整型数组input_array和output_array,其长度均为10000,分别作为待排序数据和已排序数据的存放空间,并设置一整型数组sort_time用来存放5个算法的执行时间。

之所以这样设计,是因为所有的用户定义函数都完全按照既定的“标准”设计实现,使得整个程序的可伸缩性大大增强。

排序算法的设计实现

程序中的全部5中排序算法均按照标准化的函数名、返回值和形参表设计,其形式为:

1

实现。

插入排序

插入排序是一种最简单的排序方法,它的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的有序表。

快速排序

1参见:参考资料[2]和[3]。

快速排序是对冒泡法排序的一种改进。它的基本思想是,通过一趟排序将待排记录分割成

独立的两部分,其中一部分记录均比另一部分记录小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

归并排序

归并排序的核心操作是将一位数组中前后两个相邻的有序序列归并为一个有序序列,其实

现如下:

并为相邻的有序序列,依次递归的执行下去,最终归并为一个有序序列。其实现如下:

希尔排序

希尔排序2是一种插入排序类的方法,但在时间效率上较传统的插入排序方法有较大的改进。其主要特点是,子序列的构成不再是简单的“逐段分割”,而是将相隔某个“增量”的记录组

成一个子序列。其实现如下:

2希尔排序也称作“缩小增量排序” (Diminishing Increment Sort)。

堆排序

堆排序主要包括两个步骤,即建堆;取出堆顶的最大元素,重新调整为堆。不断重复这两个过程,直到堆为空。堆排序也不依赖于原是数组的有序情况,在最佳、最差、平均情况下的时间代价均相同。其实现如下:

计时函数

计时函数使用了Windows API 函数QueryPerformanceFrequency和QueryPerformanceCounter来实现毫秒级的计时功能。该函数接受一个指向函数的指针参数,用于在两次查询机器内部计时器的计数之间插入所需要被计时的代码,再降两次查询之差除以CPU时钟频率即可得到事件经历的精确时间。其实现如下:

统计数据显示函数

对同一组数据执行了5种算法之后,产生了一组时间值,该函数用以在字符界面绘制一个时间长短的柱状图表。其实现如下:

使用说明

运行程序sort.exe后,可以看到在欢迎信息出现5秒之后,下方会显示程序主菜单,如下所示:

将会在内存中生成一随机数序列用于排序;选择V将会在内存中生成一逆序数序列用于排序;选择B将上述待排序数据送给5个排序算法分别进行排序,并记录下排序所花费的时间(单位:

毫秒);选择S将显示统计数据和图表,典型的输出如下所示;选择E、D或A分别将保存已排序数据并退出、丢弃已排序数据并退出,和显示“关于”信息。

缺陷与改进

由于时间和能力有限,故在整个设计过程中存在以下几点设计缺陷,如1)没能使用MFC 实现图形化的人机交互界面;2)没有使用交换次数来衡量算法的好坏等。

第1个问题主要原因是由于MFC中的一个很简单问题导致很多涉及到字符串的代码编译错误,延误了很多时间,在时间紧张的情况下最终没能实现图形化界面。

第2个问题是由于考虑到5种算法并不相似,很多情况下不能仅仅通过交换次数来衡量一个算法的好坏,而是同时需要考虑到诸如数据的复制、移动,甚至是自增自减操作所带来的时间开销,所以最终选择了采用直接计时后相互比较的方法来评价算法。

讨论与总结

本次课程设计在实际的编译器、操作系统环境中实现了5种常见的排序算法。通过多次不同数据的测试发现,对于同一组测试数据,各种算法每次执行的结果基本相同,在同样的硬件条件下误差不超过10毫秒,故可以通过该时间来比较算法的优劣。

特别的,当待排序的数据为一有序序列时,其典型的测试结果为:

多数情况下时间效率都比较高。但是与教科书上不相符的是归并排序和堆排序在数据量较大情况下的比较,个人认为可能存在某些与机器相关的代码导致编译器的优化造成的,至于此假设是否正确尚待考证。

其他方面,如函数结构的设计都遵循“统一”的原则,以便将来可以扩展更多的算法进行比较。所有CPP源代码采用Makefile进行依存关系的组织和自动化编译的实现,以便修改后重新编译整个程序。

参考文献

[1]Stanley B. Lippman, Josée Lajoie, Barbara E. Moo -- C++ Primer, Fourth Edition -- Addison Wesley Professional, 2005

[2]Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein -- Introduction to Algorithms, Second Edition -- The MIT Press, 2001

[3]严蔚敏、吴伟民 -- 《数据结构(C语言版)》–清华大学出版社,2006

[4] MSDN Library for Visual Studio 2005 -- Microsoft Corporation, 2005

相关文档
最新文档