当前位置:文档之家› 实验三.归并排序的分治策略设计

实验三.归并排序的分治策略设计

实验三.归并排序的分治策略设计
实验三.归并排序的分治策略设计

实验三归并排序的分治策略设计(4学时)

[实验目的]

1.熟悉二分检索问题的线性结构表示和二分检索树表示;

2.熟悉不同存储表示下求解二分检索问题的递归算法设计;

3.通过实例转换, 掌握将递归算法转换成迭代算法的方法;

4.掌握应用递归或迭代程序设计实现分治法求解问题的抽象控制策略.

[预习要求]

1.认真阅读算法设计教材和数据结构教材内容, 熟悉不同存储表示下求解二分检索问题的原理或方法;

2.针对线性结构表示和二分检索树表示设计递归算法;

3.参考教材和课堂教学内容, 根据将递归算法转换成迭代算法的一般步骤将二分检索递归算法转换成相应的迭代算法.

[实验步骤]

1. 调试线性结构表示下的快速分类与二分检索递归程序, 直至正确为止;

2. 调试线性结构表示下的快速分类与二分检索迭代程序, 直至正确为止;

3. 待各功能子程序调试完毕, 去掉测试程序, 将程序整理成功能模块存盘备用.

1.归并排序

(备注:语言C++;编译器:MS VS2008;共2个文件)

head.h文件

#include

#include

using namespace std;

void mergeSort(int *a,int left,int right);

void merge(int *a,int left,int i,int right);

main.cpp文件

#include "head.h"

void main()

{

int test[]={0,12,45,3,6,29,4,16,77};

cout<<"before:";

for(int i=0;i<=8;i++)

{

cout<

}

mergeSort(test,0,8);

cout<<"after:";

for(int i=0;i<=8;i++)

{

cout<

}

cout<<"\ndown!"<

_getche();

}

void mergeSort(int *a,int left,int right)

{

if(left

{

int i = (left+right)/2; //划分成前后两部分

mergeSort(a,left,i); //递归划分前半部分

mergeSort(a,i+1,right); //递归划分后半部分

merge(a,left,i,right); //归并

}

}

void merge(int *a,int left,int i,int right)

{

int k=0;

//k为循环标记

int s1,s2,e1,e2;

//s1表示前半部分的开始下标,s2表示后半部分开始的下标 //e1表示前半部分结束的下标,s2表示后半部分结束的下标 int *temp = new int[right-left+1];

//temp为临时存储数组的头指针

s1 = left;

e1 = i;

s2 = i+1;

e2 = right;

while((s1<=e1)&&(s2<=e2)) //循环比较,合并到数组k[] {

if(a[s1]

{

temp[k]=a[s1];

s1++;

}

else

{

temp[k]=a[s2];

s2++;

}

k++;

}

while(s1<=e1) //若前半部分有剩余,拷贝到k[]的后边

{

temp[k++]=a[s1++];

}

while(s2<=e2) //若后半部分有剩余,拷贝到k[]的后边

{

temp[k++]=a[s2++];

}

for(int j=0;j<(right-left+1);j++) //拷贝回a[]数组

{

a[left+1]=temp[j];

}

delete[](temp);

}

测试数据:0,12,45,3,6,29,4,16,77

测试结果:0,3 ,4,6,12,12,29,45,77

各种排序算法比较

排序算法 一、插入排序(Insertion Sort) 1. 基本思想: 每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。 2. 排序过程: 【示例】: [初始关键字] [49] 38 65 97 76 13 27 49 J=2(38) [38 49] 65 97 76 13 27 49 J=3(65) [38 49 65] 97 76 13 27 49 J=4(97) [38 49 65 97] 76 13 27 49 J=5(76) [38 49 65 76 97] 13 27 49 J=6(13) [13 38 49 65 76 97] 27 49 J=7(27) [13 27 38 49 65 76 97] 49 J=8(49) [13 27 38 49 49 65 76 97] Procedure InsertSort(Var R : FileType); //对R[1..N]按递增序进行插入排序, R[0]是监视哨// Begin for I := 2 To N Do //依次插入R[2],...,R[n]// begin R[0] := R[I]; J := I - 1; While R[0] < R[J] Do //查找R[I]的插入位置// begin R[J+1] := R[J]; //将大于R[I]的元素后移// J := J - 1 end R[J + 1] := R[0] ; //插入R[I] // end End; //InsertSort // 二、选择排序 1. 基本思想: 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 2. 排序过程: 【示例】: 初始关键字[49 38 65 97 76 13 27 49] 第一趟排序后13 [38 65 97 76 49 27 49] 第二趟排序后13 27 [65 97 76 49 38 49] 第三趟排序后13 27 38 [97 76 49 65 49] 第四趟排序后13 27 38 49 [49 97 65 76] 第五趟排序后13 27 38 49 49 [97 97 76]

第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.从未排序序列中挑选元素,并将其依次插入已排序序列(初始时为空)的一端的方法,称为

各种排序算法的总结和比较

各种排序算法的总结和比较 1 快速排序(QuickSort) 快速排序是一个就地排序,分而治之,大规模递归的算法。从本质上来说,它是归并排序的就地版本。快速排序可以由下面四步组成。 (1)如果不多于1个数据,直接返回。 (2)一般选择序列最左边的值作为支点数据。(3)将序列分成2部分,一部分都大于支点数据,另外一部分都小于支点数据。 (4)对两边利用递归排序数列。 快速排序比大部分排序算法都要快。尽管我们可以在某些特殊的情况下写出比快速排序快的算法,但是就通常情况而言,没有比它更快的了。快速排序是递归的,对于内存非常有限的机器来说,它不是一个好的选择。 2 归并排序(MergeSort)

归并排序先分解要排序的序列,从1分成2,2分成4,依次分解,当分解到只有1个一组的时候,就可以排序这些分组,然后依次合并回原来的序列中,这样就可以排序所有数据。合并排序比堆排序稍微快一点,但是需要比堆排序多一倍的内存空间,因为它需要一个额外的数组。 3 堆排序(HeapSort) 堆排序适合于数据量非常大的场合(百万数据)。 堆排序不需要大量的递归或者多维的暂存数组。这对于数据量非常巨大的序列是合适的。比如超过数百万条记录,因为快速排序,归并排序都使用递归来设计算法,在数据量非常大的时候,可能会发生堆栈溢出错误。 堆排序会将所有的数据建成一个堆,最大的数据在堆顶,然后将堆顶数据和序列的最后一个数据交换。接下来再次重建堆,交换数据,依次下去,就可以排序所有的数据。

Shell排序通过将数据分成不同的组,先对每一组进行排序,然后再对所有的元素进行一次插入排序,以减少数据交换和移动的次数。平均效率是O(nlogn)。其中分组的合理性会对算法产生重要的影响。现在多用D.E.Knuth的分组方法。 Shell排序比冒泡排序快5倍,比插入排序大致快2倍。Shell排序比起QuickSort,MergeSort,HeapSort慢很多。但是它相对比较简单,它适合于数据量在5000以下并且速度并不是特别重要的场合。它对于数据量较小的数列重复排序是非常好的。 5 插入排序(InsertSort) 插入排序通过把序列中的值插入一个已经排序好的序列中,直到该序列的结束。插入排序是对冒泡排序的改进。它比冒泡排序快2倍。一般不用在数据大于1000的场合下使用插入排序,或者重复排序超过200数据项的序列。

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、算法运行所需要的计算机资源的量,称为算法复杂性,主要包括时间复杂度和空间复杂度。 2、多项式10()m m A n a n a n a =+++L 的上界为O(n m )。 3、算法的基本特征:输入、输出、确定性、有限性 、可行性 。 4、如何从两个方面评价一个算法的优劣:时间复杂度、空间复杂度。 5、计算下面算法的时间复杂度记为: O(n 3) 。 for(i=1;i<=n;i++) for(j=1;j<=n;j++) {c[i][j]=0; for(k=1;k<=n;k++) c[i][j]= c[i][j]+a[i][k]*b[k][j]; } 6、描述算法常用的方法:自然语言、伪代码、程序设计语言、流程图、盒图、PAD 图。 7、算法设计的基本要求:正确性 和 可读性。 8、计算下面算法的时间复杂度记为: O(n 2) 。 for (i =1;i

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

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

几种常见内部排序算法比较

常见内部排序算法比较 排序算法是数据结构学科经典的内容,其中内部排序现有的算法有很多种,究竟各有什么特点呢?本文力图设计实现常用内部排序算法并进行比较。分别为起泡排序,直接插入排序,简单选择排序,快速排序,堆排序,针对关键字的比较次数和移动次数进行测试比较。 问题分析和总体设计 ADT OrderableList { 数据对象:D={ai| ai∈IntegerSet,i=1,2,…,n,n≥0} 数据关系:R1={〈ai-1,ai〉|ai-1, ai∈D, i=1,2,…,n} 基本操作: InitList(n) 操作结果:构造一个长度为n,元素值依次为1,2,…,n的有序表。Randomizel(d,isInverseOrser) 操作结果:随机打乱 BubbleSort( ) 操作结果:进行起泡排序 InserSort( ) 操作结果:进行插入排序 SelectSort( ) 操作结果:进行选择排序 QuickSort( ) 操作结果:进行快速排序 HeapSort( ) 操作结果:进行堆排序 ListTraverse(visit( )) 操作结果:依次对L种的每个元素调用函数visit( ) }ADT OrderableList 待排序表的元素的关键字为整数.用正序,逆序和不同乱序程度的不同数据做测试比较,对关键字的比较次数和移动次数(关键字交换计为3次移动)进行测试比较.要求显示提示信息,用户由键盘输入待排序表的表长(100-1000)和不同测试数据的组数(8-18).每次测试完毕,要求列表现是比较结果. 要求对结果进行分析.

详细设计 1、起泡排序 算法:核心思想是扫描数据清单,寻找出现乱序的两个相邻的项目。当找到这两个项目后,交换项目的位置然后继续扫描。重复上面的操作直到所有的项目都按顺序排好。 bubblesort(struct rec r[],int n) { int i,j; struct rec w; unsigned long int compare=0,move=0; for(i=1;i<=n-1;i++) for(j=n;j>=i+1;j--) { if(r[j].key

简单的归并排序算法例子

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 ; //定义顺序表类型 四、功能设计 (一)主控菜单设计

数据结构各种排序方法的综合比较

数据结构各种排序方法的综合比较 结论: 排序方法平均时间最坏时间辅助存储 简单排序O(n2) O(n2) O(1) 快速排序O(nlogn)O(n2)O(logn) 堆排序O(nlogn)O(nlogn)O(1) 归并排序O(nlogn)O(nlogn)O(n) 基数排序O(d(n+rd))O(d(n+rd))O(rd) PS:直接插入排序、冒泡排序为简单排序,希尔排序、堆排序、快速排序为不稳定排序 一、时间性能 按平均的时间性能来分,有三类排序方法: 时间复杂度为O(nlogn)的方法有:快速排序、堆排序和归并排序,其中以快速排序为最好;时间复杂度为O(n2)的有:直接插入排序、起泡排序和简单选择排序,其中以直接插入为 最好,特别是对那些对关键字近似有序的记录序列尤为如此; 时间复杂度为O(n)的排序方法只有,基数排序。 当待排记录序列按关键字顺序有序时,直接插入排序和起泡排序能达到O(n)的时间复杂度;而对于快速排序而言,这是最不好的情况,此时的时间性能蜕化为O(n2),因此是应该尽量避免的情况。简单选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布而改变。 二、空间性能 指的是排序过程中所需的辅助空间大小。 1. 所有的简单排序方法(包括:直接插入、起泡和简单选择)和堆排序的空间复杂度为O(1); 2. 快速排序为O(logn),为栈所需的辅助空间; 3. 归并排序所需辅助空间最多,其空间复杂度为O(n ); 4.链式基数排序需附设队列首尾指针,则空间复杂度为O(rd)。 三、排序方法的稳定性能 1. 稳定的排序方法指的是,对于两个关键字相等的记录,它们在序列中的相对位置,在排序之前和经过排序之后,没有改变。 2. 当对多关键字的记录序列进行LSD方法排序时,必须采用稳定的排序方法。 3. 对于不稳定的排序方法,只要能举出一个实例说明即可。 4. 快速排序和堆排序是不稳定的排序方法

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

归并排序算法实现(迭代和递归)\递归实现归并排序的原理如下: 递归分割: 递归到达底部后排序返回: 最终实现排序: #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

计算机算法设计与分析习题和答案解析

《计算机算法设计与分析》习题及答案 一.选择题 1、二分搜索算法是利用(A )实现的算法。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法 2、下列不是动态规划算法基本步骤的是(A )。 A、找出最优解的性质 B、构造最优解 C、算出最优解 D、定义最优解 3、最大效益优先是( A )的一搜索方式。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 4. 回溯法解旅行售货员问题时的解空间树是( A )。 A、子集树 B、排列树 C、深度优先生成树 D、广度优先生成树 5.下列算法中通常以自底向上的方式求解最优解的是( B )。 A、备忘录法 B、动态规划法 C、贪心法 D、回溯法 6、衡量一个算法好坏的标准是(C )。 A 运行速度快 B 占用空间少 C 时间复杂度低 D 代码短 7、以下不可以使用分治法求解的是(D )。 A 棋盘覆盖问题 B 选择问题 C 归并排序 D 0/1背包问题 8. 实现循环赛日程表利用的算法是( A )。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法 9.下面不是分支界限法搜索方式的是( D )。 A、广度优先 B、最小耗费优先 C、最大效益优先 D、深度优先 10.下列算法中通常以深度优先方式系统搜索问题解的是( D )。 A、备忘录法 B、动态规划法 C、贪心法 D、回溯法 11.备忘录方法是那种算法的变形。(B ) A、分治法 B、动态规划法 C、贪心法 D、回溯法 12.哈夫曼编码的贪心算法所需的计算时间为( B )。 A、O(n2n) B、O(nlogn) C、O(2n) D、O(n) 13.分支限界法解最大团问题时,活结点表的组织形式是( B )。 A、最小堆 B、最大堆 C、栈 D、数组 14.最长公共子序列算法利用的算法是( B )。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 15.实现棋盘覆盖算法利用的算法是( A )。 A、分治法 B、动态规划法 C、贪心法 D、回溯法 16.下面是贪心算法的基本要素的是( C )。 A、重叠子问题 B、构造最优解 C、贪心选择性质 D、定义最优解 17.回溯法的效率不依赖于下列哪些因素( D ) A.满足显约束的值的个数 B. 计算约束函数的时间 C.计算限界函数的时间 D. 确定解空间的时间 18.下面哪种函数是回溯法中为避免无效搜索采取的策略( B ) A.递归函数 B.剪枝函数C。随机数函数 D.搜索函数 19. ( D )是贪心算法与动态规划算法的共同点。

十大排序法综合排序的设计和实现

十大排序法对大量数据综合排序的设计和实现 文档信息 开发小组: 组长:于微 成员:郑鸿、张雪莹、杨宝英 单位:软件设计工作室文档类型:软件开发用技术文档当前版本:Microsoft Word 作者:杨宝英、郑鸿 完成时间:2010年10月10日软件信息 系统名称:十大排序法对大量数据综合排序 运行环境Windows Seven 环境下Visual C+ + 6.0版本 参与编写:于微、郑鸿、张雪莹、杨宝英 日期:2010年10月5号-2010年10月10号 系统简介:系统面向大众人群,囊括了起泡排序、插入排序、二分排序、选择排序、希尔排序、快速排序、堆排序、桶排序、基数排序、 二路归并排序这十个常用排序,此系统可对一百万个随机数进 行综合排序,计算各排序时间,以比较各排序工作的效率。

一、序言 (3) 二、需求分析说明书 (3) 2.1系统介绍 (3) 2.2系统面向的用户群体 (3) 2.3系统的功能性需求 (3) 2.4系统的非功能性需求 (4) 2.4.1用户界面需求 (4) 2.4.2软硬件环境需求 (4) 三、可行性分析报告 (4) 四、概要设计 (5) 五、详细设计 (5) 5.1主函数于各模块的关系 (5) 5.2各模块功能函数 (6) 5.2.1基数排序函数的实现 (6) 5.2.2起泡排序函数的实现 (8) 5.2.3选择排序函数的实现 (9) 5.2.4插入排序函数的实现 (10) 5.2.5希尔排序函数的实现 (11) 5.2.6二分排序函数的实现 (11) 5.2.7快速排序函数的实现 (13) 5.2.8桶排序函数的实现 (14) 5.2.9堆排序函数的实现 (16) 5.2.10二路归并排序函数的实现 (18) 5.2.11过滤重复数据的实现 (20) 六、使用说明 (20) 七、心得体会 (23) 参考资料 (23)

第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. 在堆排序、快速排序和归并排序中, 若只从存储空间考虑,则应首先选取堆排序方法,其次选取快速排序方法,最后选取归并排序方法;若只从排序结果的稳定性考虑,则应选取归并排序方法; / 若只从平均情况下最快考虑,则应选取快速排序方法; 若只从最坏情况下最快并且要节省内存考虑,则应选取堆排序方法。

各种排序法比较

各种排序法的比较 按平均时间将排序分为四类: (1)平方阶(O(n2))排序 一般称为简单排序,例如直接插入、直接选择和冒泡排序; (2)线性对数阶(O(nlgn))排序 如快速、堆和归并排序; (3)O(n1+£)阶排序 £是介于0和1之间的常数,即0<£<1,如希尔排序; (4)线性阶(O(n))排序 如桶、箱和基数排序。 各种排序方法比较: 简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。 影响排序效果的因素: 因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法 应综合考虑下列因素: ①待排序的记录数目n; ②记录的大小(规模); ③关键字的结构及其初始状态; ④对稳定性的要求; ⑤语言工具的条件; ⑥存储结构; ⑦时间和辅助空间复杂度等。 不同条件下,排序方法的选择 (1)若n较小(如n≤50),可采用直接插入或直接选择排序。 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。 (2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜; (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。 快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短; 堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。 若要求排序稳定,则可选用归并排序。从单个记录起进行两两归并,排序算法并不值得提倡,通常可以将它和直接插入排序结合在一起使用。先利用直接插入排序求得较长的有序子文件,然后再两两归并之。因为直接插入排序是稳定的,所以改进后的归并排序仍是稳定的。

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

沈阳化工大学实验报告 课程名称算法设计与分析 项目名称归并排序(分治)和插入排序的比较 学院应用技术学院 专业计中职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语言

一、设计思想 插入排序:首先,我们定义我们需要排序的数组,得到数组的长度。如果数组只有一个数字,那么我们直接认为它已经是排好序的,就不需要再进行调整,直接就得到了我们的结果。否则,我们从数组中的第二个元素开始遍历。然后,启动主索引,我们用curr当做我们遍历的主索引,每次主索引的开始,我们都使得要插入的位置(insertIndex)等于-1,即我们认为主索引之前的元素没有比主索引指向的元素值大的元素,那么自然主索引位置的元素不需要挪动位置。然后,开始副索引,副索引遍历所有主索引之前的排好的元素,当发现主索引之前的某个元素比主索引指向的元素的值大时,我们就将要插入的位置(insertIndex)记为第一个比主索引指向元素的位置,跳出副索引;否则,等待副索引自然完成。副索引遍历结束后,我们判断当前要插入的位置(insertIndex)是否等于-1,如果等于-1,说明主索引之前元素的值没有一个比主索引指向的元素的值大,那么主索引位置的元素不要挪动位置,回到主索引,主索引向后走一位,进行下一次主索引的遍历;否则,说明主索引之前insertIndex位置元素的值比主索引指向的元素的值大,那么,我们记录当前主索引指向的元素的值,然后将主索引之前从insertIndex位置开始的所有元素依次向后挪一位,这里注意,要从后向前一位一位挪,否则,会使得数组成为一串相同的数字。最后,将记录下的当前索引指向的元素的值放在要插入的位置(insertIndex)处,进行下一次主索引的遍历。继续上面的工作,最终我们就可以得到我们的排序结果。插入排序的特点在于,我们每次遍历,主索引之前的元素都是已经排好序的,我们找到比主索引指向元素的值大的第一个元素的位置,然后将主索引指向位置的元素插入到该位置,将该位置之后一直到主索引位置的元素依次向后挪动。这样的方法,使得挪动的次数相对较多,如果对于排序数据量较大,挪动成本较高的情况时,这种排序算法显然成本较高,时间复杂度相对较差,是初等通用排序算法中的一种。 选择排序:选择排序相对插入排序,是插入排序的一个优化,优化的前提是我们认为数据是比较大的,挪动数据的代价比数据比较的代价大很多,所以我们选择排序是追求少挪动,以比较次数换取挪动次数。首先,我们定义我们需要排序的数组,得到数组的长度,定义一个结果数组,用来存放排好序的数组,定义一个最小值,定义一个最小值的位置。然后,进入我们的遍历,每次进入遍历的时候我们都使得当前的最小值为9999,即认为每次最小值都是最大的数,用来进行和其他元素比较得到最小值,每次认为最小值的位置都是0,用来重新记录最小值的位置。然后,进入第二层循环,进行数值的比较,如果数组中的某个元素的值比最小值小,那么将当前的最小值设为元素的值,然后记录下来元素的位置,这样,当跳出循环体的时候,我们会得到要排序数组中的最小值,然后将最小值位置的数值设置为9999,即我们得到了最小值之后,就让数组中的这个数成为最大值,然后将结果数组result[]第主索引值位置上的元素赋值为最小值,进行下一次外层循环重复上面的工作。最终我们就得到了排好序的结果数组result[]。选择排序的优势在于,我们挪动元素的次数很少,只是每次对要排序的数组进行整体遍历,找到其中的最小的元素,然后将改元素的值放到一个新的结果数组中去,这样大大减少了挪动的次序,即我们要排序的数组有多少元素,我们就挪动多少次,而因为每次都要对数组的所有元素进行遍历,那么比较的次数就比较多,达到了n2次,所以,我们使用选择排序的前提是,认为挪动元素要比比较元素的成本高出很多的时候。他相对与插入排序,他的比较次数大于插入排序的次数,而挪动次数就很少,元素有多少个,挪动次数就是多少个。 希尔排序:首先,我们定义一个要排序的数组,然后定义一个步长的数组,该步长数组是由一组特定的数字组成的,步长数组具体得到过程我们不去考虑,是由科学家经过很长时间计算得到的,已经根据时间复杂度的要求,得到了最适合希尔排序的一组步长值以及计算

归并排序的设计与实现

题目: 归并排序的设计与实现 初始条件: 理论:学习了《数据结构》课程,掌握了基本的数据结构和常用的算法; 实践:计算机技术系实验室提供计算机及软件开发环境。 要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求) 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

相关主题
文本预览
相关文档 最新文档