数据结构课程设计二路归并排序说明书

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

前言

1.1排序的重要性

生活中,无时不刻不充满这排序,比如:班级同学的成绩排名问题,公司产值高低的问题等等,解决这些问题的过程中,都涉及到了一个数据结构的构造思想过程。数据结构中的排序,也有很多种,如:插入排序、交换排序、选择排序等等,此时我们就要注意选择具有优解的算法,将一个数据元素(或记录)的任意序列,重新排列成一个有序的排列,便于我们查找。

假设含有n个记录的序列为{R1,R2,Rn},其相应的关键字序列为{K1,K2,…,Kn}需确定1,2…n的一种排序P1,P2…Pn,使其相应的关键字满足如下的非递减的关系:Kp1≤Kp2≤…≤Kpn,即按关键字{Rp1,Rp2,…,Rpn}有序的排列,这样的一种操作称为排序。一般情况下,排序又分为内部排序和外部排序。而在内部排序中又含有很多排序方法,就其全面性能而言,很难提出一种被认为是最好的方法,因为每一种方法都有它的优缺点,适合在不同的环境下使用。我们学习的排序有:直接插入排序、折半插入排序、希尔排序、快速排序、基数排序、归并排序等。本次课题研究中,我主要进行了二路归并排序的研究和学习。

1.2设计的背景和意义

排序是计算机领域的一类非常重要的问题,计算机在出来数据的过程中,有25%的时间花在了排序上,有许多的计算机设备,排序用去计算机处理数据时间的一半以上,这对于提高计算机的运行速度有一定的影响。此时排序算法的高效率显得尤为重要。

在排序算法汇中,归并排序(Merging sort)是与插入排序、交换排序、选择排序不同的另一类排序方法。归并的含义是将两个或两个以上的有序表组合成一个新的有序表。归并排序可分为多路归并排序,两路归并排序,既可用于内排序,也可以用于外排序。这里仅对内排序的两路归并排序进行讨论。

而我们这里所探究学习的二路归并排序,设计思路更加清晰、明了,程序本身也不像堆结构那样复杂,同时时间复杂度仅为0(N),同时在处理大规模归并排序的时候,排序速度也明显优于冒泡法等一些排序算法,提高排序算法的效率。

正文

2.1设计内容

设计一个利用二路归并算法实现的排序算法,针对输入的一组无序的数,利用栈或者数组机芯存储,然后进行数据的两两分组、比较,构造新的栈或者数组,依次类推,直到得到一个有序数组或者栈,最后输出有序数据,得到有序数据。

2.2设计要求

假设初始序列含有n 个数据(n是已经确定的数据个数),首先把n 个记录看成n

个长度为1的有序序列,进行两两归并,得到[n/2]个长度为2的有序序列,再两两归并直到所有记录归并成一个长度为n的有序序列为止。

2.3设计思想

对于任意一组数据,先利用栈或者数组将数据存储起来,其中,我们会用到线性表的顺序存储和链式存储两种存储方法。然后对存储的数据进行查找和筛选、排序,在出栈的过程中,同时对所取数据进行分组、排列,再次构造新的存储栈或者数组,依次类推,直到得到一个有序的数据时,执行出栈命令,输出最后的排序结果。

为了更清晰地说清楚这里的思想,大家来看图1,我们将本是无序的数组序列{16,7,13,10,9,15,3,2,5,8,12,1,11,4,6,14},通过两两合并排序后,再合并,最终获得了一个有序的数组。仔细观察它的形状,很像一棵倒置的完全二叉树,利用两两的比较,一次进行递归排序,最终得到一个从小到大的有序序列。

图 1

2.4 主要模块

主要模块式有四个阶段,依次是:输入一组无序的数列,用数据结构或者链式结构进行存储,然后进行查找、分组,进行最后的归并排序。(如图2所示)

图 2

2.5排序设计内容

此次操作要用到顺序结构的存储,顺序表的查找,以及二路归并排序。

2.5.1 顺序表的存储

首先利用顺序存储结构,把所有学生的成绩按每个班,每个学校,每个县,每个市,用线性表的顺序存储机构分别存储起来。

顺序表的基本操作如下:

Initlist(&L) 操作结果:构造一个空的线性表L; Destroylist(&L) 操作结果:销毁线性表L;

Clearlist((&lL) 操作结果:将L重置为空表(线性表L已经存在);

Iiselength(L) 操作结果:返回L中数据元素的个数;GetElem(L,I,&e) 操作结果:用e返回L中第i个数据元素的值;

2.5.2 顺序表的查找

Int Search-Sep(SSTable ST , KeyType key)

{//在顺序表ST中顺序查找其关键字等于Key的数据元素。若找到,则函数值为该元素在表中的位置,否则为0

ST.elem[0].Key=key; 哨兵;

For(i=ST.length; !EQ(ST.elem[i].key.key)) 从后往前找;

Return I; 找不到是i为0;

}

//Search-Sep

2.5.3 归并排序

代码:

/* 对顺序表L作归并排序 */

void MergeSort(SqList *L)

{

MSort(L->r,L->r,1,L->length);

}

2.6算法设计

本次设计主要用用到下面的算法:

2.6.1归并排序算法的实现

递归算法就是对n个数据进行两两归并,得到[n/2]个长度为2的有序序列,再两两归并直到所有记录归并成一个长度为n的有序序列为止。

递归算法实现中,最重要的就是对[n/2]进行很多次的归并递归排序算法的设计,调用函数MSort中采用了递归的算法思想,用较简短的语句,实现了多次递归排序。假设现在要对数组{50,10,90,30,70,40,80,60,20}进行排序,L.length=9,一下就是MSort 主要代码及实现过程。

/* 将SR[s..t]归并排序为TR1[s..t] */

1 void MSort(int SR[],int TR1[],int s, int t)

2 {

3int m;

4int TR2[MAXSIZE+1];

5if(s==t)

6TR1[s]=SR[s];

7Else

8{

9m=(s+t)/2; /* 将SR[s..t]平分为SR[s..m]和SR[m+1..t] */ 10MSort(SR,TR2,s,m); /* 递归地将SR[s..m]归并为有序的TR2[s..m] */

11MSort(SR,TR2,m+1,t); /* 递归地将SR[m+1..t]归并为有序TR2[m+1..t] */

12Merge(TR2,TR1,s,m,t); /* 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] */

13}

14}

1) MSort被调用时,SR与TR1都是{50,10,90,30,70,40,80,60,20},s=1,t=9,最终我们的目的就是要将TR1中的数组排好顺序。

2) 第5行,显然s不等于t,执行第8~13行语句块。

3) 第9行,m=(1+9)/2=5。m就是序列的正中间下标

4) 此时第10行,调用“MSort(SR,TR2,1,5);”的目标就是将数组SR中的第1~5的关键字归并到有序的TR2(调用前TR2为空数组),第11行,调用“MSort(SR,TR2,6,9);”的目标就是将数组SR中的第6~9的关键字归并到有序的TR2。也就是说,在调用这两句代码之前,代码已经准备将数组分成两组。如图4所示:

图4

5) 第12行,函数Merge的代码细节一会再讲,调用“Merge(TR2,TR1,1,5,9);”的

相关文档
最新文档