归并排序的设计与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
题目: 归并排序的设计与实现
初始条件:
理论:学习了《数据结构》课程,掌握了基本的数据结构和常用的算法;
实践:计算机技术系实验室提供计算机及软件开发环境。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
1、系统应具备的功能:
(1)输入一组数,用递归和非递归程序实现归并排序;
(2)分析归并排序的复杂度;
(3)将归并排序的思想用于外部排序中。
2、数据结构设计;
3、主要算法设计;
4、编程及上机实现;
5、撰写课程设计报告,包括:
(1)设计题目;
(2)摘要和关键字;
(3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、设计体会等;
(4)结束语;
(5)参考文献。
时间安排:2007年7月2日-7日(第18周)
7月2日查阅资料
7月3日系统设计,数据结构设计,算法设计
7月4日-5日编程并上机调试
7月6日撰写报告
7月7日验收程序,提交设计报告书。
指导教师签名: 2007年7月2日
系主任(或责任教师)签名: 2007年7月2日
归并排序的设计和实现
摘要:该程序主要由五个部分组成:把一组待排的数据信息放在结构体里,2-路归并排序,对数组作一趟归并排序,对数组作归并排序,主函数。
关键字:模型化, 2-路归并, 一趟归并, 归并
0.引言
归并排序是一种稳定的内部排序,“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。无论是顺序存储结构还是链表存储结构,都可在O(m+n)的时间量级上实现。利用归并的思想容易实现排序。
2—路归并排序:假设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到不小于n/2整数个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止。
1.需求分析
(1)通过建立一个结构体,用来存放数据信息,包括数据的个数,本身记录。
(2)2-路归并排序的算法,实现两两归并。(3)主函数初始化数据,及打印数据结果。
2.数据结构设计
用结构体存储待排的数据。
#include "stdio.h"
#include
#define MAXNUM 100
#define TRUE 1
#define FALSE 0
typedef int DataType;
typedef struct
{
int n; /* n为文件中的记录个数,n int record[MAXNUM]; } SortObject; 3.算法设计 3.1 2-路归并排序的非递归算法 //将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] void merge(RcdType SR[],RcdType&TR[],int i,int m,int n) { for(j=m+1,k=I;i<=m&&j<=n;k++) { //将SR中记录由小到大的并入TR if(LQ(SR[i].key,SR[j].key)) TR[k]=SR[i++]; else TR[k]=SR[j++]; } if(i<=m) TR[k..n]=SR[i..m]; //将剩余的SR[i..m]复制到TR if(j<=n) TR[k..n]=SR[j..n]; //将剩余的SR[i..m]复制到TR }//merge 3.2 2-路归并排序的递归形式 void Msort(RcdType SR[],RcdType&TR1[],int s,int t) { //将SR归并排序为TR if(s==t) TR1[s]=SR[s]; else { m=(s+t)/2; //将平分为SR[s..t]和SR[m+1..t] Msort(SR,TR2,s,m); // 递归的将SR[s..m]归并为有序的TR2[s..m] Msort(SR,TR2,m+1,t); //递归地将SR[m+1..t]归并为有序的TR{m+1..t} Merge(TR2,TR1,s,m,t); // 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] } }//mergesort 3.3 对顺序表L作归并排序 Void mergesort(SqList &L) { Msort(L.r,L.r,1,L.length); }//mergesort 3.4 非递归形式归并算法 void merge(int r[], int r1[], int low, int m, int high) { /* r[low]到r[m]和r[m+1]到r[right]是两个有序段 */ int i = low, j = m + 1, k = low; while ( i <= m && j <= high ) { /* 反复复制两个段的第一个记录中较小的 */ if (r[i] <= r[j] ) r1[k++] = r[i++]; else r1[k++] = r[j++]; } while (i <= m) r1[k++] = r[i++]; /* 复制第一个段的剩余记录 */ while (j <= high) r1[k++] = r[j++];/* 复制第二个段的剩余记录 */ } 3.5 对 r 做一趟归并的算法 void mergePass(int r[], int r1[], int n, int length) { int i = 0, j; /* length为本趟归并的有序子段的长度 */ while(i + 2*length - 1 < n) { /* 归并长length的两个子段*/ merge(r, r1, i, i+length-1, i + 2*length - 1); i += 2*length; } if(i + length - 1 < n - 1) /* 剩下两段,后一段长度小于 length */ merge(r, r1, i, i+length-1, n-1); else /* 将剩下的一段复制到数组r1 */ for(j = i; j < n; j++) r1[j] = r[j]; } 3.6 对整个数据进行归并的算法 void mergeSort(SortObject * p ) { int record[MAXNUM]; int length = 1; int i; while (length < p->n) { /* 一趟归并,结果存放在数组record中*/ mergePass(p->record, record, p->n, length); length *= 2; /* 一趟归并,结果存回 */ mergePass(record, p->record, p->n, length); length *= 2; } } 4. 程序实现