几种常见排序方法的比较

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

重庆邮电大学移通学院《计算机软件技术基础》

课程报告

题目几种常见排序方法的比较

姓名谢枞

学号0111100320

班级01111003

专业通信工程

2012年6 月4日

摘要

该程序是用C++语言实现的,在程序中随机生成N个数据,对这些数进行多种方法的排序,所用的这些排序方法都是在数据结构课中学习过的比如:插入排序、快速排序、冒泡排序等,而且还要对各个排序做出相应的比较。

该演示程序以用户和计算机的对话方式执行,每次测试完毕,列表显示各种比较指标值。

最后对结果作出了简单分析并将结果排序,包括对各组数据得出结果波动大小给予解析。

关键字:插入排序、冒泡排序、比较的个数、改变的个数、所用的时间。

目录

摘要 (Ⅰ)

目录 (Ⅱ)

1问题描述 (1)

题目内容 (1)

基本要求 (1)

测试数据 (1)

2需求分析 (2)

输入输出的形式和输入值的范围 (2)

程序所能达到的功能 (2)

3概要设计 (3)

程序所需的抽象数据类型 (3)

系统功能模块 (3)

外部功能模块图 (3)

主函数功能模块图 (3)

4详细设计 (4)

4.1 整个程序的流程图 (4)

4.2 插入排序及其主要代码 (5)

4.3 二路合并排序及其主要代码 (6)

4.4 冒泡排序及其主要代码 (7)

5 调试分析 (8)

5.1 调试分析结果 (9)

6 总结 (10)

1问题描述

1.1题目内容

本演示程序对以下几种常用的内部排序算法进行实测比较:起泡排序、直接插入排序、二路合并排序。

主要工作是设法在已知算法中的适当位置插入对关键字的比较次数和移动

次数的计数操作。程序还可以考虑几组数据的典型性,如:正序、逆序和不同程度的乱序。注意采用分块调试的方法。

1.2基本要求

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

2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”下,用户可由键盘输入待排序表的表长和不同的测试数据的数组,每次测试完毕,列表显示各种比较指标值。

3.最后对结果作出简单分析,包括对各组数据得出结果波动大小给予解析。

1.3 测试数据

由函数rand随机产生的数据。

2 需求分析

2.1输入输出的形式和输入值的范围

由于程序中所需的数据都是有函数随机生成的整形数,不需要用户自己输入,用户只需要对演示程序中的一些提示做一些必要的选择以便于程序的执行。

程序输出的是对五种排序做的一些比较,即输出五种排序各排序过程中所比较的数据的个数,交换的数据的次数,和排序完成所用的时间。六种排序依次在计算机终端上显示,便于用户观察。

输入值的范围等价于程序中随机生成的数据的个数,即待排序表的表长不小于100,至少要用5组不同的输入数据体比较,比较的指标为:有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次的移动),在该程序中,随机生成的数据个数被初始化为了10000,数据越大就越容易比较。

2.2程序所能达到的功能

输入N个随机整数,对这些数进行多种方法进行排序,并对这些排序做比较,在屏幕上输出每种排序方法所比较的次数,交换的次数,和用掉的时间。

任意性:系统首先生成10000个随机整数,然后分别用不同的排序方法对其进行升序排序,给出每种方法的比较次数或所用时间

友好性:界面要友好,输入有提示,尽量展示人性化

可读性:源程序代码清晰、有层次

健壮性:用户输入非法数据时,系统要及时给出警告信息

3 概要设计

3.1程序所需的抽象数据类型

typedef struct StudentData

{

int num; //存放关键字,如零时变量,还有哨兵

}Data;

typedef struct LinkList

{

int Length; //存放随机数的个数

Data Record[MAXSIZE];//用数组存放所有的随机数

}LinkList;

3.2系统功能模块

3.2.1 主函数功能模块图

图 3.2.2 主函数功能模块图

4.1整个程序的流程图

·4.2 插入排序及其主要代码

直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,它的基本

操作是将一个纪录插入到已排好序的有序表中,从而得到一个新的、纪录数增1的有序表。

例如,已知待排序的一组纪录的初始排列如下所示:

R(49)、R(38)、R(65)、R(97)、R(76)、R(13)、R(27)、R(49)……(4-1)假设在排序过程中,前4个记录已按关键字递增的次序重新排列,构成一个含4个纪录的有序序列

{ R(38)、R(49)、R(65)、R(97) } (4-2)现要将式(4-1)中的第5个纪录插入上述序列,以得到一个新的含5个纪录的有序序列,则首先要在式(4-2)的序列中进行查找以确定R(76)、所应插入的位置,然后进行插入。假设从R(97)、起向左进行顺序查找,由于65<76<97,

则R(76)应插入在R(65)和R(97)之间,从而等到下列新的有序序列

{ R(38)、R(49)、R(65)、R(76)、R(97) } (4-3)称从式(4-2)到(4-3)的过程为一趟直接插入排序。一般情况下,第i趟直接插入排序的操作为:在含有i-1个纪录的有序子序列r[1...i-1]中插入一个记录r[i]后,变成含有i个记录的有序子序列r[1...i];并且,和顺序查找类似,为了在查找插入位置的过程中避免数组下标出界,在r[0]处设置监视哨。在自i-1起往前搜索的过程中,可以同时后移记录。整个排序过程为进行n-1趟插入,即:先将序列中的第1个记录看成是一个有序的子序列,然后从第2个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。代码如下:

void ShellSort(LinkList* L, int dlta[], int t,int* CmpNum, int* ChgNum)

{

int k;

for (k=0; k

ShellInsert(L,dlta[k],CmpNum,ChgNum);

}

void ShellInsert(LinkList* L,int dk, int* CmpNum, int* ChgNum)

{

int i, j;

Data Temp;

for(i=dk; iLength;i++)

{

if( LT(L->Record[i].num, L->Record[i-dk].num, CmpNum) )

{

memcpy(&Temp,&L->Record[i],sizeof(Data));

for(j=i-dk; j>=0 && LT(Temp.num, L->Record[j].num, CmpNum) ; j-=dk)

{

(*ChgNum)++;

(*ChgNum)++;

memcpy(&L->Record[j+dk],&L->Record[j],sizeof(Data));

}

memcpy(&L->Record[j+dk],&Temp,sizeof(Data));

}

}

相关文档
最新文档