文档库 最新最全的文档下载
当前位置:文档库 › 二路归并和多路归并排序.pdf

二路归并和多路归并排序.pdf

第10章排序自测题答案

第9章排序自测卷姓名班级 一、填空题(每空1分,共24分) 1. 大多数排序算法都有两个基本的操作:比较和移动。 2. 在对一组记录(54,38,96,23,15,72,60,45,83)进行直接插入排序时,当把第7个记录60插 入到有序表时,为寻找插入位置至少需比较6 次。 3. 在插入和选择排序中,若初始数据基本正序,则选用插入;若初始数据基本反序,则选用 选择。 4. 在堆排序和快速排序中,若初始记录接近正序或反序,则选用堆排序;若初始记录基本 无序,则最好选用快速排序。 5. 对于n个记录的集合进行冒泡排序,在最坏的情况下所需要的时间是O(n2) 。若对其进行快速 排序,在最坏的情况下所需要的时间是O(n2)。 6. 对于n个记录的集合进行归并排序,所需要的平均时间是O(nlog2n),所需要的附加空间 是O(n) 。 7.对于n个记录的表进行2路归并排序,整个归并排序需进行┌log2n┐趟(遍)。 8. 设要将序列(Q, H, C, Y, P, A, M, S, R, D, F, X)中的关键码按字母序的升序重新排列,则: 冒泡排序一趟扫描的结果是H C Q P A M S R D F X Y; 初始步长为4的希尔(shell)排序一趟的结果是P A C S Q H F X R D M Y ; 二路归并排序一趟扫描的结果是H Q C Y A P M S D R F X; 快速排序一趟扫描的结果是 F H C D P A M Q R S Y X; 堆排序初始建堆的结果是A D C R F Q M S Y P H X。 9. 在堆排序、快速排序和归并排序中, 若只从存储空间考虑,则应首先选取方法,其次选取快速排序方法,最后选取归并排序方法; 若只从排序结果的稳定性考虑,则应选取归并排序方法; 若只从平均情况下最快考虑,则应选取堆排序、快速排序和归并排序方法; 若只从最坏情况下最快并且要节省内存考虑,则应选取堆排序方法。 二、单项选择题(每小题1分,共18分) ( C )1.将5个不同的数据进行排序,至多需要比较次。 A. 8 B. 9 C. 10 D. 25 (C)2.排序方法中,从未排序序列中依次取出元素与已排序序列(初始时为空)中的元素进行比较,将其放入已排序序列的正确位置上的方法,称为 A. 希尔排序B. 冒泡排序C. 插入排序D. 选择排序(D)3.从未排序序列中挑选元素,并将其依次插入已排序序列(初始时为空)的一端的方法,称为

算法设计实验一归并排序(分治)和插入排序的比较分析

沈阳化工大学实验报告 课程名称算法设计与分析 项目名称归并排序(分治)和插入排序的比较 学院应用技术学院 专业计中职1401 指导教师张雪 报告人张庭浩学号 1422030125 实验时间 2016.11.05 提交时间 2016.11.05

一、实验目的 1.理解和掌握分治算法的相关内容。 2.具体完成插入排序和归并排序性能的比较。 二、实验内容 编写一个真随机函数,随机产生大量数字。在产生相同的一组大量随机数字后,分别用归并排序和插入排序两种算法进行排序,并通过时间函数分别计算出运行的时间。 三、伪代码 1.归并排序 /*数组a[]是原始数组,数组b[]是目标数组*/ 归并排序(数组a[],数组b[]){ `分割与归并(数组a[],0, a.length,数组b[]) } /*通过递归把要排序的子序列分的足够小*/ 分割与归并(数组a[],起始位置,结束位置,数组b[]){ if(结束位置- 起始位置< 2) 返回 中间位置= (起始位置+结束位置)/2 分割与归并(数组a[],起始位置,中间位置,数组b[]) 分割与归并(数组a[],中间位置,结束位置,数组b[]) 归并(数组a[],起始位置,中间位置,结束位置,数组b[]) 拷贝(数组a[],起始位置,结束位置,数组b[]) } 归并(数组a[],起始位置,中间位置,结束位置,数组b[]){ i0 = 起始位置,i1 = 中间位置 for j = 起始位置到结束位置 if(i0 < 中间位置且(i1 > 结束位置或a[i0] <= a[i1]){ //当i0没有超过中间位置时,有两种情况要将a[i0]复制到b[j]上: //1.i1已经超过结束位置,只要把剩下的复制过来就好; //2.a[i0]比a[i1]小 b[j]=a[i0] i0++ } else { b[j]=a[i1] i1++ } }

C (++)内部排序汇总(快速排序&冒泡排序&堆排序&选择排序&插入排序&归并排序)

#include #include #include #include #define M 30001 random(int a[30001]) { int i; for(i=1;i<30001;i++) a[i]=rand()%30001; }//随机生成30000个数函数 int change1(char a[81]) { int b=0,n,i; for(i=0;a[i]!=0;i++); n=i-1; for(;i>1;i--) b+=((int)pow(10,n+1-i))*(a[i-1]-48); if(a[0]=='-') b=b*(-1); else b+=((int)pow(10,n))*(a[0]-48); return b; }//字符转化成整型 insort(int a[30001]) { int i,j,temp,temp1,n; int count=0; n=30001; for(i=1;i=0;j--)/* 每次循环完毕数组的0到i-1项为一个有序的序列*/ { count=0;/*这里count是标记位,可以减少比较次数*/ if(a[j]>temp) { temp1=a[j+1]; a[j+1]=a[j]; a[j]=temp1;

count++; }//满足条件,前移 if(count==0) break;//位置恰当,退出 } } }//insort插入排序函数 selsort(int a[30001]) { int i,j,temp; for(i=1;i<30000;i++) for(j=i+1;j<30001;j++) if(a[i]>a[j]) { temp=a[j]; a[j]=a[i]; a[i]=temp; } }//选择排序 bubsort(int a[30001]) { int i,j,temp; for(i=1;i<30001;i++) for(j=30000;j>i;j--) { if(a[j-1]>a[j]) { temp=a[j-1]; a[j-1]=a[j]; a[j]=temp; } } }//冒泡排序 int partition(int a[30001],int low,int high)

数据结构第九章排序习题与答案

习题九排序 一、单项选择题 1.下列内部排序算法中: A.快速排序 B.直接插入排序 C. 二路归并排序 D.简单选择排序 E. 起泡排序 F.堆排序 (1)其比较次数与序列初态无关的算法是() (2)不稳定的排序算法是() (3)在初始序列已基本有序(除去n 个元素中的某 k 个元素后即呈有序, k<

排序算法比较实验报告

信息学部算法分析 上机报告 学号0901******** 姓名陈龙 指导老师秦明 时间2011.11.1~11.23

一.上机实验题目 实验1 比较归并排序和快速排序的区别。 实验2 利用贪心算法对背包问题进行求解。 二.算法设计思路 归并排序: 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列,设定两个指针,最初位置分别为两个已经排序序列的起始位置,比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置,重复步骤直到某一指针达到序列尾,将另一序列剩下的所 有元素直接复制到合并序列尾。 快速排序: 设置两个变量I、J,排序开始的时候:I=0,J=N-1;以第一个数组元素作为关键数据,赋值给key,即key=A[0];从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与key交换;从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与key交换;重复第3、4、5步,直到I=J;(3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i,j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。) 背包问题: 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 。可以压缩空间,f[v]=max{f[v],f[v-c[i]]+w[i]}

三. 源程序 归并排序 #include #include # define N 50 int b[N],a[N]; int n,i; void Merge (int low, int mid,int high) //合并 { int i; int l=low,h=mid+1,k=l; while ((l<=mid) && (h<=high)) //部分合并 { if (a[l]<=a[h]) b[k++]=a[l++]; else b[k++]=a[h++]; } if(l>mid) while (h<=high) b[k++]=a[h++]; //转储剩余部分 else while(l<=mid) b[k++]=a[l++]; for (i=0;i<=high;i++) //将b数组转储到a a[i]=b[i]; } int Merge2 (int l,int h) //分类 { for (i=0;i

归并排序上机题

实验一归并排序 一、实验目的 (1)掌握归并排序算法的思想; (2)掌握归并排序算法的程序实现。 二、实验环境 Windows 2000以上版本的操作系统,运用java或C语言实现该算法。 三、实验内容 在main函数中定义数A[]={52,49,80,36,14,58,61,23,97},调用归并排序函数MergeSort对A[]中的数据进行排序,调试并观察排序过程。

C语言实现: 1.#include 2.typedef int RecType;//要排序元素类型 3.void Merge(RecType *R,int low,int m,int high) 4.{ 5.//将两个有序的子文件R[low..m)和R[m+1..high]归并成一个有序的子文件 R[low..high] 6.int i=low,j=m+1,p=0; //置初始值 7. RecType *R1; //R1是局部向量 8. R1=(RecType *)malloc((high-low+1)*sizeof(RecType)); 9.if(!R1) 10. { 11.return; //申请空间失败 12. } 13.while(i<=m&&j<=high) //两子文件非空时取其小者输出到R1[p]上 14. { 15. R1[p++]=(R[i]<=R[j])?R[i++]:R[j++]; 16. } 17.while(i<=m) //若第1个子文件非空,则复制剩余记录到R1中 18. { 19. R1[p++]=R[i++]; 20. } 21.while(j<=high) //若第2个子文件非空,则复制剩余记录到R1中 22. { 23. R1[p++]=R[j++]; 24. } 25.for(p=0,i=low;i<=high;p++,i++) 26. { 27. R[i]=R1[p]; //归并完成后将结果复制回R[low..high] 28. } 29.} 30.void MergeSort(RecType R[],int low,int high) 31.{ 32.//用分治法对R[low..high]进行二路归并排序 33.int mid; 34.if(low

简单的归并排序算法例子

import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; public class GuiBing { public static void main(String[] args) throws Exception { int datalength=1000000; GuiBing gui=new GuiBing(); int[] array1=gui.createArray(datalength); int[] array2=gui.createArray(datalength); Thread.sleep(20000); long startTime = System.nanoTime();//纳秒精度 long begin_freeMemory=Runtime.getRuntime().freeMemory(); int[] final_array=gui.guibing(array1,array2); boolean result=gui.testResult(final_array); long end_freeMemory=Runtime.getRuntime().freeMemory(); System.out.println("result===="+result); long estimatedTime = System.nanoTime() - startTime; System.out.println("elapsed time(纳秒精 度):"+estimatedTime/100000000.0); System.out.println("allocated memory:"+(begin_freeMemory-end_freeMemory)/1000.0+" KB"); Thread.sleep(20000); } /** * 显示数组的内容 * @param array */ private static void dispalyData(int[] array) { for(int i=0;i

数据结构课程设计排序实验报告

《数据结构》课程设计报告 专业 班级 姓名 学号 指导教师 起止时间

课程设计:排序综合 一、任务描述 利用随机函数产生n个随机整数(20000以上),对这些数进行多种方法进行排序。(1)至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。并把排序后的结果保存在不同的文件中。 (2)统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。 要求:根据以上任务说明,设计程序完成功能。 二、问题分析 1、功能分析 分析设计课题的要求,要求编程实现以下功能: (1)随机生成N个整数,存放到线性表中; (2)起泡排序并计算所需时间; (3)简单选择排序并计算时间; (4)希尔排序并计算时间; (5)直接插入排序并计算所需时间; (6)时间效率比较。 2、数据对象分析 存储数据的线性表应为顺序存储。 三、数据结构设计 使用顺序表实现,有关定义如下: typedef int Status; typedef int KeyType ; //设排序码为整型量 typedef int InfoType; typedef struct { //定义被排序记录结构类型 KeyType key ; //排序码 I nfoType otherinfo; //其它数据项 } RedType ; typedef struct { RedType * r; //存储带排序记录的顺序表 //r[0]作哨兵或缓冲区 int length ; //顺序表的长度 } SqList ; //定义顺序表类型 四、功能设计 (一)主控菜单设计

归并排序实验报告

篇一:归并排序与快速排序实验报告 一、实验内容: 对二路归并排序和快速排序对于逆序的顺序数的排序时间复杂度比较。 二、所用算法的基本思想及复杂度分析: 1、归并排序 1)基本思想:运用分治法,其分治策略为: ①划分:将待排序列 r1,r2,……,rn划分为两个长度相等的子序列 r1,……,rn/2和rn/2+1,……,rn。 ②求解子问题:分别对这两个子序列进行排序,得到两个有序子序列。 ③合并:将这两个有序子序列合并成一个有序子序列。 2)复杂度分析: 二路归并排序的时间代价是o(nlog2n)。二路归并排序在合并过程中需要与原始记录序列同样数量的存储空间,因此其空间复杂性o(n)。 2、快速排序: 1)基本思想:运用分治法,其分治策略为: ①划分:选定一个记录作为轴值,以轴值为基准将整个序列划分为两个子序列 r1……ri-1和ri+1……rn,轴值的位置i在划分的过程中确定,并且前一个子序列中记录的值均小于或等于轴值,后一个子序列中记录的值均大于或等于轴值。 ②求解子问题:分别对划分后的每一个子序列递归处理。 ③合并:由于对子序列r1……ri-1和ri+1……rn的排序是就地进行的,所以合并不需要执行任何操作。 2)复杂度分析: 快速排序在平均时间复杂性是o(nlog2n)。最坏的情况下是o(n^2)。 三、源程序及注释: 1、归并排序 #include<iostream> #include<fstream> #include windows.h using namespace std; void merge(int r[],int r1[],int s,int m,int t ) } int mergesort(int r[],int r1[],int s,int t) { } void main() int i=s; int j=m+1; int k=s; while(i<=m&&j<=t) {} if(i<=m)while(i<=m) r1[k++]=r[i++];//第一个没处理完,进行收尾if(r[i]<=r[j])r1[k++]=r[i++];//取r[i]和r[j]中较小的放入r1[k]中else r1[k++]=r[j++]; else while(j<=t) r1[k++]=r[j++];//第二个没处理完,进行收尾for(int l=0;l<k;l++) { } r[l]=r1[l];//将合并完成后的r1[]序列送回r[]中if(s==t)r1[s]=r[s]; else{int m; m=(s+t)/2; mergesort(r,r1,s,m);//归并排序前半个子序列 mergesort(r,r1,m+1,t); //归并排序后半个子序列 merge(r1,r,s,m,t);//合并两个已排序的子序列 }return 0; int a[100000]; int a1[10000];

归并排序算法实现 (迭代和递归)

归并排序算法实现(迭代和递归)\递归实现归并排序的原理如下: 递归分割: 递归到达底部后排序返回: 最终实现排序: #include void merge(int *array, int low, int center, int high) { if(low >= high) return; int m = center - low + 1; int n = high - center; int L[m], R[n]; for(int i=0; i R[j]) array[k] = R[j++]; else array[k] = L[i++];

} while(i #include

归并排序算法的基本思想及算法实现示例

归并排序算法的基本思想及算法实现示例 归并排序(Merge Sort)是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。 两路归并算法 1、算法基本思路 设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。 (1)合并过程 合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较R[i]和R[j]的关键字,取关键字较小的记录复制到R1[p]中,然后将被复制记录的指针i或j加1,以及指向复制位置的指针p加1。 重复这一过程直至两个输入的子文件有一个已全部复制完毕(不妨称其为空),此时将另一非空的子文件中剩余记录依次复制到R1中即可。 (2)动态申请R1 实现时,R1是动态申请的,因为申请的空间可能很大,故须加入申请空间是否成功的处理。 2、归并算法 void Merge(SeqList R,int low,int m,int high) {//将两个有序的子文件R[low..m)和R[m+1..high]归并成一个有序的 //子文件R[low..high] int i=low,j=m+1,p=0;//置初始值 RecType *R1;//R1是局部向量,若p定义为此类型指针速度更快 R1=(ReeType *)malloc((high-low+1)*sizeof(RecType)); if(! R1) //申请空间失败 Error("Insufficient memory available!"); while(i<=m&&j<=high) //两子文件非空时取其小者输出到R1[p]上 R1[p++]=(R[i].key<=R[j].key)?R[i++]:R[j++]; while(i<=m) //若第1个子文件非空,则复制剩余记录到R1中 R1[p++]=R[i++]; while(j<=high) //若第2个子文件非空,则复制剩余记录到R1中 R1[p++]=R[j++]; for(p=0,i=low;i<=high;p++,i++) R=R1[p];//归并完成后将结果复制回R[low..high] } //Merge 归并排序 归并排序有两种实现方法:自底向上和自顶向下。

第8章排序练习题答案

第8章排序练习题答案 填空题 1. 大多数排序算法都有两个基本的操作:比较和移动。 2. 在对一组记录(54,38,96,23,15,72,60,45,83)进行直接插入排序时,当把第7个记录60插 入到有序表时,为寻找插入位置至少需比较 3 次。 3. 在插入和选择排序中,若初始数据基本正序,则选用插入;若初始数据基本反序,则选用 选择。 正序时两种方法移动次数均为0,但比较次数量级不同,插入法:n-1即O(n),选择法:O(n2) 反序时两种方法比较次数量级相同,均为O(n2),但移动次数不同,插入法:O(n2),选择法:3(n-1)即O(n) 4. 在堆排序和快速排序中,若初始记录接近正序或反序,则选用堆排序;若初始记录基本 无序,则最好选用快速排序。 5. 对于n个记录的集合进行冒泡排序,在最坏的情况下所需要的时间复杂度是O(n2) 。若对其进 行快速排序,在最坏的情况下所需要的时间复杂度是O(n2)。 6. 对于n个记录的集合进行归并排序,所需要的平均时间是O(nlog2n){ ,所需要的附加空间是O(n) 。 7.对于n个记录的表进行2路归并排序,整个归并排序需进行┌log2n┐趟(遍)。 8. 设要将序列(Q, H, C, Y, P, A, M, S, R, D, F, X)中的关键码按字母序的升序重新排列,则: 冒泡排序一趟扫描的结果是H C Q P A M S R D F X Y; 二路归并排序一趟扫描的结果是H Q C Y A P M S D R F X; 快速排序一趟扫描的结果是 F H C D P A M Q R S Y X; 堆排序初始建堆的结果是Y S X R P C M H Q D F A。(大根堆) 9. 在堆排序、快速排序和归并排序中, 若只从存储空间考虑,则应首先选取堆排序方法,其次选取快速排序方法,最后选取归并排序方法;若只从排序结果的稳定性考虑,则应选取归并排序方法; / 若只从平均情况下最快考虑,则应选取快速排序方法; 若只从最坏情况下最快并且要节省内存考虑,则应选取堆排序方法。

第13周内排序第5讲-归并排序

归并排序是多次将相邻两个或两个以上的有序表合并成一个新的有序表。 最简单的归并是将相邻两个有序的子表合并成一个有序的表,即二路归并排序。1 、归并的思路

一次二路归并:将两个位置相邻的记录有序子序列归并为一个记录的有序序列。有序 序列R [low..high] 有序子序列R [low..mid]有序子序列R [mid+1..high] R [low..high]

void Merge (RecType R[],int low,int mid,int high) {RecType *R1; int i=low,j=mid+1,k=0; //k 是R1的下标,i 、j 分别为第1、2段的下标 R1=(RecType *)malloc((high-low+1)*sizeof(RecType));while (i<=mid &&j<=high) if (R[i].key<=R[j].key)//将第1段中的记录放入R1中 {R1[k]=R[i];i++;k++;} else //将第2段中的记录放入R1中 {R1[k]=R[j];j++;k++;} Merge():一次二路归并,将两个相邻的有序子序列归并为一个有 序序列。 空间复杂度为O(high-low+1) 2、二路归并算法

while(i<=mid)//将第1段余下部分复制到R1 {R1[k]=R[i];i++;k++;} while(j<=high)//将第2段余下部分复制到R1 {R1[k]=R[j];j++;k++;} for(k=0,i=low;i<=high;k++,i++)//将R1复制回R中R[i]=R1[k]; free(R1); }

排序问题实验报告

2010级数据结构实验报告 实验名称:排序 姓名:袁彬 班级: 2009211120 班内序号: 09 学号: 09210552 日期: 2010 年12 月19 日 1.实验要求 试验目的: 通过选择试验内容中的两个题目之一,学习、实现、对比各种排序的算法,掌握各种排序算法的优缺点,以及各种算法使用的情况。 试验内容: 题目一: 使用简单数组实现下面各种排序算法,并进行比较。 排序算法如下: ①插入排序; ②希尔排序 ③冒泡排序; ④快速排序; ⑤简单选择排序; ⑥堆排序 ⑦归并排序 ⑧基数排序 ⑨其他。 具体要求如下: ①测试数据分为三类:正序,逆序,随机数据。 ②对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为三次移动)。 ③对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙。 ④对②和③的结果进行分析,验证上述各种算法的时间复杂度。 ⑤编写main()函数测试各种排序算法的正确性。 题目二: 使用链表实现下面各种排序算法,并进行比较。 排序算法如下: ①插入排序; ②冒泡排序; ③快速排序;

④简单选择排序; ⑤其他。 具体要求如下: ①测试数据分为三类:正序,逆序,随机数据。 ②对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为三次移动)。 ③对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙(选作) ④对②和③的结果进行分析,验证上述各种算法的时间复杂度。 ⑤编写main()函数测试各种排序算法的正确性。 2. 程序分析 2.1 存储结构 程序中每一个算法均是用一个类来表示的,类中有自己的构造函数、排序函数。 程序的储存结构采用数组。数组的第一个位置不存储数据。数据从第二个位置开始。数组中的相对位置为数组的下标。 2.2 关键算法分析 ㈠、关键算法: 1、插入排序函数:Insert s ort(int n) ①、从2开始做循环,依次和前面的数进行比较:for(int i=2;i<=n;i++) ②、如果后面的比前面的小,则进行前移:if(number[i]=1;d=d/2) ②、在自己的间隔中进行简单插入排序,进行循环:for(int i=d+1;i<=n;i++) ③、如果后面的数据比前面的小,进行前移:if(number[i]0;j=j-d) ⑥、大的数据后移:number[j+d]=number[j]; ⑦、哨兵归位:number[j+d]=number[0]; 3、冒泡排序函数:Bubble s ort(int n) ①、设置有序无序的边界点:int pos=n; ②、当边界点不为空进行循环:while(pos!=0) ③、边界点传递给bound:int bound=pos; ④、从开始到边界点进行循环:for(int i=1;inumber[i+1]) ⑥、交换:number[0]=number[i];number[i]=number[i+1];number[i+1]=number[0]; ⑦、从小设置边界点:pos=i; 4、一趟快速排序函数:partion(int first,int end) ①、传递设置整个数据的起点和终点:int i=first;int j=end; ②、设置中轴:number[0]=number[i]; ③、当end大于first进行循环:while(i

各种排序实验报告

【一】需求分析 课程题目是排序算法的实现,课程设计一共要设计八种排序算法。这八种算法共包括:堆排序,归并排序,希尔排序,冒泡排序,快速排序,基数排序,折半插入排序,直接插入排序。 为了运行时的方便,将八种排序方法进行编号,其中1为堆排序,2为归并排序,3为希尔排序,4为冒泡排序,5为快速排序,6为基数排序,7为折半插入排序8为直接插入排序。 【二】概要设计 1.堆排序 ⑴算法思想:堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。将序列所存储的元素A[N]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的元素均不大于(或不小于)其左右孩子(若存在)结点的元素。算法的平均时间复杂度为O(N log N)。 ⑵程序实现及核心代码的注释: for(j=2*i+1; j<=m; j=j*2+1) { if(j=su[j]) break; su[i]=su[j]; i=j; } su[i]=temp; } void dpx() //堆排序 { int i,temp; cout<<"排序之前的数组为:"<=0; i--) { head(i,N); } for(i=N-1; i>0; i--) {

temp=su[i]; su[i]=su[0]; su[0]=temp; head(0,i-1); } cout<<"排序之后的数组为:"<

归并排序分治策略的设计与实现

实验名称归并排序分治策略的设计与实现实验方案实验成绩实验日期实验室信息系统设计与仿真室I 实验操作 实验台号班级姓名实验结果 一、实验目的 1、熟悉分治法求解问题的抽象控制策略; 2、熟悉在顺序存储表示下求解分类问题的递归算法设计; 3、通过实例转换, 掌握分治法应用。 二、实验任务 ①从文件中读取数据信息; ②利用归并排序算法,进行排序; ③输出排序结果。 三、实验设计方案 1、结构体设计 用数组存放排序数据。 2、自定义函数设计 ①函数原型声明 int input(int A[]); //从文件读入待排序的数据 void merge(int A[],int low,int mid,int high); // 两个相邻有序数组的归并 void mergesort(int A[],int low,int high); // 归并排序 void input(int A[], int n); // 输出排序结果 ②两个相邻的有序子数组的合并 思路:从两个已排好序的子数组的首元素开始,依次比较大小,按从小到大的顺序存放在b[]数组中,然后转存到A[]数组中。 void merge(int A[],int low,int mid,int high) { int b[N]; int i,j,k = 0; int l = low; //已排序部分1的起始下标 int h = mid+1; //已排序部分2的起始下标 while(l <= mid && h <= high) //两个有序部分合并到b数组中 if(A[l] < A[h]) b[k++] = A[l++]; else

多路归并排序 外部排序算法

关于多路归并排序外部排序败者树技术积累2009-11-24 21:52:06 阅读453 评论0 字号:大中小 编程珠玑第一个case是有关一个技巧性解决外部排序问题的。问题很巧妙的解决了,但一开始提到的利用归并排序进行外部排序的算法仍值得仔细探究一下,毕竟本科时学的不是很深入。 先来看内部排序中最简单的2路归并排序算法。 算法核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列,给定数组中序列界限i、m、n,用2个下标变量分别从i和j=m+1开始逐个往后处理,先比较,小的写到结果序列的当前遍历下标k中,相应下标自增继续比较直到某个序列的下标走到边界,再将另外一个序列的剩余元素拷贝到结果序列中。 算法可用递归或递推实现,从相邻的两两元素开始不断调用上面的核心操作组成较长有序序列直到完成整个序列。 算法进行一趟归并就得到一个局部有序的完整新序列,n个元素共需要log2n趟归并,每趟完成比较操作n次(1次得到序列的1个值),得到的新序列写到结果序列空间中,下一趟之前要先将结果序列复制一份到临时空间,下一趟归并在临时空间上进行。因此时间复杂度nlog2n,空间上除了原始序列空间n、结果序列空间n,还需要辅助临时空间n。 接下来看外部排序。外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行多路归并排序。 多路归并排序算法在常见数据结构书中都有涉及。从2路到多路(k路),增大k可以减少外存信息读写时间,但k个归并段中选取最小的记录需要比较k-1次,为得到u个记录的一个有序段共需要(u-1)(k-1)次,若归并趟数为s次,那么对n个记录的文件进行外排时,内部归并过程中进行的总的比较次数为s(n-1)(k-1),也即(向上取整)(logkm)(k-1)(n-1)=(向上取整)(log2m/log2k)(k-1)(n-1),而(k-1)/log2k随k增而增因此内部归并时间随k增长而增长了,抵消了外存读写减少的时间,这样做不行,由此引出了“败者树”tree of loser的使用。在内部归并过程中利用败者树将k个归并段中选取最小记录比较的次数降为(向上取整)(log2k)次使总比较次数为(向上取整)(log2m)(n-1),与k无关。 败者树是完全二叉树,因此数据结构可以采用一维数组。其元素个数为k个叶子结点、k-1个比较结点、1个冠军结点共2k个。ls[0]为冠军结点,ls[1]--ls[k-1]为比较结点,ls[k]--ls[2k-1]为叶子结点(同时用另外一个指针索引b[0]--b[k-1]指向)。另外bk为一个附加的辅助空间,不属于败者树,初始化时存着MINKEY的值。 多路归并排序算法的过程大致为:首先将k个归并段中的首元素关键字依次存入

相关文档