数据结构实验-归并排序算法
数据结构课程设计快速排序和归并排序
XX学院信息科学与工程系课程设计说明书课程名称:数据结构课程代码:题目: 快速排序与归并排序年级/专业/班:学生姓名: 奉XX学号: 1440000000指导教师: 易开题时间: 2015 年 12 月 30 日完成时间: 2016 年 1 月 10 日目录摘要 (1)一、引言 (3)二、设计目的与任务 (3)1、课程设计目的 (3)2、课程设计的任务 (3)三、设计方案 (3)1、需求分析 (3)2、概要设计 (4)3、详细设计 (5)4、程序清单 (13)四、调试分析与体会 (19)五、运行结果 (20)六、结论 (24)七、致谢 (24)八、参考文献 (25)摘要数据结构课程设计,列举了数据结构课程设计实例,通过综合训练,能够培养学生实际分析问题、解决问题、编程和动手操作等多方面的能力,最终目的是帮助学生系统地掌握数据结构的基本内容,并运用所学的数据结构知识去解决实际问题。
其中内容包括数组、链接表、栈和队列、递归、树与森林、图、堆与优先级队列、集合与搜索结构、排序、索引与散列结构等关键字:数据结构;分析;掌握AbstractData structure course design, lists the data structure course design as an example, through the comprehensive training, to cultivate students' practical analysis and solve problems in many aspects, programming, and hands-on ability, the ultimate goal is to help students to systematically master the basic content of data structure, and using the data structure of knowledge to solve practical problems. Content including array, linked list, stack and queue, recursion, tree and forest, graph, heap and priority queue, the structure of the collection and search, sorting, indexing and hashing structure, etcKeywords:data structure;Analysis;master《数据结构》课程设计----快速排序与归并排序一、引言二、将一组数据运用快速排序与归并排序进行排序,要求使用递归与非递归方法三、本次课程设运用到了数组、链接表、栈、递归、排序等结构。
数据结构实验报告——排序
1.实验要求【实验目的】学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
【实验内容】使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。
2. 程序分析2.1 存储结构存储结构:数组2.2 关键算法分析//插入排序void InsertSort(int r[], int n) {int count1=0,count2=0;插入到合适位置for (int i=2; i<n; i++){r[0]=r[i]; //设置哨兵for (int j=i-1; r[0]<r[j]; j--) //寻找插入位置r[j+1]=r[j]; //记录后移r[j+1]=r[0];count1++;count2++;}for(int k=1;k<n;k++)cout<<r[k]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; }//希尔排序void ShellSort(int r[], int n){int i;int d;int j;int count1=0,count2=0;for (d=n/2; d>=1; d=d/2) //以增量为d进行直接插入排序{for (i=d+1; i<n; i++){r[0]=r[i]; //暂存被插入记录for (j=i-d; j>0 && r[0]<r[j]; j=j-d)r[j+d]=r[j]; //记录后移d个位置r[j+d]=r[0];count1++;count2=count2+d;}count1++;}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; }//起泡排序void BubbleSort(int r[], int n) {插入到合适位置int temp;int exchange;int bound;int count1=0,count2=0;exchange=n-1; //第一趟起泡排序的范围是r[1]到r[n]while (exchange) //仅当上一趟排序有记录交换才进行本趟排序{bound=exchange;exchange=0;for(int j=0;j<bound;j++) //一趟起泡排序{count1++; //接下来有一次比较if(r[j]>r[j+1]){temp=r[j]; //交换r[j]和r[j+1]r[j]=r[j+1];r[j+1]=temp;exchange=j; //记录每一次发生记录交换的位置count2=count2+3; //移动了3次}}}for(int i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;}//快速排序一次划分int Partition(int r[], int first, int end,int &count1,int &count2){int i=first; //初始化int j=end;while (i<j){while (i<j && r[i]<= r[j]){j--; //右侧扫描count1++;}count1++;if (i<j){temp=r[i]; //将较小记录交换到前面r[i]=r[j];r[j]=temp;i++;count2=count2+3;}while (i<j && r[i]<= r[j]){i++; //左侧扫描count1++;}count1++;if (i<j){temp=r[j];r[j]=r[i];r[i]=temp; //将较大记录交换到后面j--;count2=count2+3;}}return i; //i为轴值记录的最终位置}//快速排序void QuickSort(int r[], int first, int end,int &count1,int &count2){if (first<end){ //递归结束int pivot=Partition(r, first, end,count1,count2); //一次划分QuickSort(r, first, pivot-1,count1,count2);//递归地对左侧子序列进行快速排序QuickSort(r, pivot+1, end,count1,count2); //递归地对右侧子序列进行快速排序}}//简单选择排序Array void SelectSort(int r[ ], int n){int i;int j;int index;int temp;int count1=0,count2=0;for (i=0; i<n-1; i++) //对n个记录进行n-1趟简单选择排序{index=i;for(j=i+1;j<n;j++) //在无序区中选取最小记录{count1++; //比较次数加一if(r[j]<r[index]) //如果该元素比现在第i个位置的元素小index=j;}count1++; //在判断不满足循环条件j<n时,比较了一次if(index!=i){temp=r[i]; //将无序区的最小记录与第i个位置上的记录交换r[i]=r[index];r[index]=temp;count2=count2+3; //移动次数加3 }}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;}//筛选法调整堆void Sift(int r[],int k,int m,int &count1,int &count2) //s,t分别为比较和移动次数{int i;int j;int temp;i=k;j=2*i+1; //置i为要筛的结点,j为i的左孩子while(j<=m) //筛选还没有进行到叶子{if(j<m && r[j]<r[j+1]) j++; //比较i的左右孩子,j为较大者count1=count1+2; //该语句之前和之后分别有一次比较if(r[i]>r[j])break; //根结点已经大于左右孩子中的较大者else{temp=r[i];r[i]=r[j];r[j]=temp; //将根结点与结点j交换i=j;j=2*i+1; //下一个被筛结点位于原来结点j的位置count2=count2+3; //移动次数加3 }}}//堆排序void HeapSort(int r[],int n){int count1=0,count2=0; //计数器,计比较和移动次数int i;int temp;for(i=n/2;i>=0;i--) //初始建堆,从最后一个非终端结点至根结点Sift(r,i,n,count1,count2) ;for(i=n-1; i>0; i--) //重复执行移走堆顶及重建堆的操作{temp=r[i]; //将堆顶元素与最后一个元素交换r[i]=r[0];r[0]=temp; //完成一趟排序,输出记录的次序状态Sift(r,0,i-1,count1,count2); //重建堆}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;}//一次归并void Merge(int r[], int r1[], int s, int m, int t){int i=s;int j=m+1;int k=s;while (i<=m && j<=t){if (r[i]<=r[j])r1[k++]=r[i++]; //取r[i]和r[j]中较小者放入r1[k]elser1[k++]=r[j++];}if (i<=m)while (i<=m) //若第一个子序列没处理完,则进行收尾处理r1[k++]=r[i++];elsewhile (j<=t) //若第二个子序列没处理完,则进行收尾处理r1[k++]=r[j++];}//一趟归并void MergePass(int r[ ], int r1[ ], int n, int h){int i=0;int k;while (i<=n-2*h) //待归并记录至少有两个长度为h的子序列{Merge(r, r1, i, i+h-1, i+2*h-1);i+=2*h;}if (i<n-h)Merge(r, r1, i, i+h-1, n); //待归并序列中有一个长度小于h else for (k=i; k<=n; k++) //待归并序列中只剩一个子序列r1[k]=r[k];}//归并排序void MergeSort(int r[ ], int r1[ ], int n ){int h=1;int i;while (h<n){MergePass(r, r1, n-1, h); //归并h=2*h;MergePass(r1, r, n-1, h);h=2*h;}for(i=1;i<n;i++)cout<<r[i]<<" ";cout<<endl;}void Newarray(int a[],int b[],int c[]) {cout<<"新随机数组:";c[0]=0;a[0]=0;b[0]=0;for(int s=1;s<11;s++){a[s]=s;b[s]=20-s;c[s]=rand()%50+1;cout<<c[s]<<" ";}cout<<endl;}2.3 其他3. 程序运行结果void main(){srand(time(NULL));const int num=11; //赋值int a[num];int b[num];int c[num];int c1[num];c[0]=0;a[0]=0;b[0]=0;Newarray(a,b,c);cout<<"顺序数组:";for(int j=1;j<num;j++)cout<<a[j]<<" ";cout<<endl;cout<<"逆序数组:";for(j=1;j<num;j++)cout<<b[j]<<" ";cout<<endl;cout<<endl;cout<<"插入排序结果为:"<<"\n";InsertSort(a,num);InsertSort(b,num);InsertSort(c,num);cout<<endl;Newarray(a,b,c);cout<<"希尔排序结果为:"<<"\n";ShellSort(a, num);ShellSort(b, num);ShellSort(c, num);cout<<endl;Newarray(a,b,c);cout<<"起泡排序结果为:"<<"\n";BubbleSort(a, num);BubbleSort(b, num);BubbleSort(c, num);cout<<endl;int count1=0,count2=0;Newarray(a,b,c);cout<<"快速排序结果为:"<<"\n";QuickSort(a,0,num-1,count1,count2);for(int i=1;i<num;i++)cout<<a[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; count1=0,count2=0;QuickSort(b,0,num-1,count1,count2);for(i=1;i<num;i++)cout<<b[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl; count1=0,count2=0;QuickSort(c,0,num-1,count1,count2);for(i=1;i<num;i++)cout<<c[i]<<" ";cout<<endl;cout<<"比较次数为"<<count1<<" 移动次数为"<<count2<<endl;cout<<endl;cout<<endl;Newarray(a,b,c);cout << "简单选择排序结果为:" << "\n";SelectSort(a,num);SelectSort(b,num);SelectSort(c,num);cout<<endl;Newarray(a,b,c);cout << "堆排序结果为:" << "\n";HeapSort(a, num);HeapSort(b, num);HeapSort(c, num);cout<<endl;Newarray(a,b,c);cout << "归并排序结果为:" << "\n";MergeSort(a, c1,num );MergeSort(b, c1,num );MergeSort(c, c1,num );}。
数据结构实验报告-排序
数据结构实验报告-排序一、实验目的本实验旨在探究不同的排序算法在处理大数据量时的效率和性能表现,并对比它们的优缺点。
二、实验内容本次实验共选择了三种常见的排序算法:冒泡排序、快速排序和归并排序。
三个算法将在同一组随机生成的数据集上进行排序,并记录其性能指标,包括排序时间和所占用的内存空间。
三、实验步骤1. 数据的生成在实验开始前,首先生成一组随机数据作为排序的输入。
定义一个具有大数据量的数组,并随机生成一组在指定范围内的整数,用于后续排序算法的比较。
2. 冒泡排序冒泡排序是一种简单直观的排序算法。
其基本思想是从待排序的数据序列中逐个比较相邻元素的大小,并依次交换,从而将最大(或最小)的元素冒泡到序列的末尾。
重复该过程直到所有数据排序完成。
3. 快速排序快速排序是一种分治策略的排序算法,效率较高。
它将待排序的序列划分成两个子序列,其中一个子序列的所有元素都小于等于另一个子序列的所有元素。
然后对两个子序列分别递归地进行快速排序。
4. 归并排序归并排序是一种稳定的排序算法,使用分治策略将序列拆分成较小的子序列,然后递归地对子序列进行排序,最后再将子序列合并成有序的输出序列。
归并排序相对于其他算法的优势在于其稳定性和对大数据量的高效处理。
四、实验结果经过多次实验,我们得到了以下结果:1. 冒泡排序在数据量较小时,冒泡排序表现良好,但随着数据规模的增大,其性能明显下降。
排序时间随数据量的增长呈平方级别增加。
2. 快速排序相比冒泡排序,快速排序在大数据量下的表现更佳。
它的排序时间线性增长,且具有较低的内存占用。
3. 归并排序归并排序在各种数据规模下都有较好的表现。
它的排序时间与数据量呈对数级别增长,且对内存的使用相对较高。
五、实验分析根据实验结果,我们可以得出以下结论:1. 冒泡排序适用于数据较小的排序任务,但面对大数据量时表现较差,不推荐用于处理大规模数据。
2. 快速排序是一种高效的排序算法,适用于各种数据规模。
数据结构课程设计实践报告
数据结构实验报告本文是范文,仅供参考写作,禁止抄袭本文内容上传提交,违者取消写作资格,成绩不合格!实验名称:排序算法比较提交文档学生姓名:提交文档学生学号:同组成员名单:指导教师姓名:排序算法比较一、实验目的和要求1、设计目的1.掌握各种排序的基本思想。
2.掌握各种排序方法的算法实现。
3.掌握各种排序方法的优劣分析及花费的时间的计算。
4.掌握各种排序方法所适应的不同场合。
2、设计内容和要求利用随机函数产生30000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并统计每一种排序上机所花费的时间二、运行环境(软、硬件环境)软件环境:Vc6.0编程软件运行平台: Win32硬件:普通个人pc机三、算法设计的思想1、冒泡排序:bubbleSort()基本思想: 设待排序的文件为r[1..n]第1趟(遍):从r[1]开始,依次比较两个相邻记录的关键字r[i].key和r[i+1].key,若r[i].key>r[i+1].key,则交换记录r[i]和r[i+1]的位置;否则,不交换。
(i=1,2,...n-1)第1趟之后,n个关键字中最大的记录移到了r[n]的位置上。
第2趟:从r[1]开始,依次比较两个相邻记录的关键字r[i].key和r[i+1].key,若r[i].key>r[i+1].key,则交换记录r[i]和r[i+1]的位置;否则,不交换。
(i=1,2,...n-2)第2趟之后,前n-1个关键字中最大的记录移到了r[n-1]的位置上,作完n-1趟,或者不需再交换记录时为止。
2、选择排序:selSort()每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序不像冒泡排序算法那样先并不急于调换位置,第一轮(k=1)先从array[k]开始逐个检查,看哪个数最小就记下该数所在的位置于minlIndex中,等一轮扫描完毕,如果找到比array[k-1]更小的元素,则把array[minlIndex]和a[k-1]对调,这时array[k]到最后一个元素中最小的元素就换到了array[k-1]的位置。
算法—4.归并排序(自顶向下)
算法—4.归并排序(⾃顶向下)1.基本思想将两个有序的数组归并成⼀个更⼤的有序数组,很快⼈们就根据这个操作发明了⼀种简单的递归排序算法:归并排序。
要将⼀个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。
你将会看到,归并排序最吸引⼈的性质是它能够保证将任意长度为N的数组排序所需时间和NlogN成正⽐;它的主要缺点则是它所需的额外空间和N成正⽐。
简单的归并排序如下图所⽰:原地归并的抽象⽅法:实现归并的⼀种直截了当的办法是将两个不同的有序数组归并到第三个数组中,实现的⽅法很简单,创建⼀个适当⼤⼩的数组然后将两个输⼊数组中的元素⼀个个从⼩到⼤放⼊这个数组中。
public void merge(Comparable[] a, int lo, int mid, int hi){int i = lo, j = mid+1;//将a[lo..hi]复制到aux[lo..hi]for (int k = lo; k <= hi; k++) {aux[k] = a[k];}//归并回到a[lo..hi]for (int k = lo; k <= hi; k++) {if(i > mid){a[k] = aux[j++];}else if(j > hi){a[k] = aux[i++];}else if(less(aux[j], aux[i])){a[k] = aux[j++];}else{a[k] = aux[i++];}}}以上⽅法会将⼦数组a[lo..mid]和a[mid+1..hi]归并成⼀个有序的数组并将结果存放在a[lo..hi]中。
在归并时(第⼆个for循环)进⾏了4个条件判断:左半边⽤尽(取右半边的元素)、右半边⽤尽(取左半边的元素)、右半边的当前元素⼩于左半边的当前元素(取右半边的元素)以及右半边的当前元素⼤于等于左半边的当前元素(取左半边的元素)。
2.具体算法/*** ⾃顶向下的归并排序* @author huazhou**/public class Merge extends Model{private Comparable[] aux; //归并所需的辅助数组public void sort(Comparable[] a){System.out.println("Merge");aux = new Comparable[a.length]; //⼀次性分配空间sort(a, 0, a.length - 1);}//将数组a[lo..hi]排序private void sort(Comparable[] a, int lo, int hi){if(hi <= lo){return;}int mid = lo + (hi - lo)/2;sort(a, lo, mid); //将左半边排序sort(a, mid+1, hi); //将右半边排序merge(a, lo, mid, hi); //归并结果}} 此算法基于原地归并的抽象实现了另⼀种递归归并,这也是应⽤⾼效算法设计中分治思想的最典型的⼀个例⼦。
数据结构之各种排序的实现与效率分析
各种排序的实现与效率分析一、排序原理(1)直接插入排序基本原理:这是最简单的一种排序方法,它的基本操作是将一个记录插入到已排好的有序表中,从而得到一个新的、记录增1的有序表。
效率分析:该排序算法简洁,易于实现。
从空间来看,他只需要一个记录的辅助空间,即空间复杂度为O(1).从时间来看,排序的基本操作为:比较两个关键字的大小和移动记录。
当待排序列中记录按关键字非递减有序排列(即正序)时,所需进行关键字间的比较次数达最小值n-1,记录不需移动;反之,当待排序列中记录按关键字非递增有序排列(即逆序)时,总的比较次数达最大值(n+2)(n-1)/2,记录移动也达到最大值(n+4)(n-2)/2.由于待排记录是随机的,可取最大值与最小值的平均值,约为n²/4.则直接插入排序的时间复杂度为O(n²).由此可知,直接插入排序的元素个数n越小越好,源序列排序度越高越好(正序时时间复杂度可提高至O(n))。
插入排序算法对于大数组,这种算法非常慢。
但是对于小数组,它比其他算法快。
其他算法因为待的数组元素很少,反而使得效率降低。
插入排序还有一个优点就是排序稳定。
(2)折半插入排序基本原理:折半插入是在直接插入排序的基础上实现的,不同的是折半插入排序在将数据插入一个有序表时,采用效率更高的“折半查找”来确定插入位置。
效率分析:由上可知该排序所需存储空间和直接插入排序相同。
从时间上比较,折半插入排序仅减少了关键字间的比较次数,为O(nlogn)。
而记录的移动次数不变。
因此,折半查找排序的时间复杂度为O(nlogn)+O(n²)= O(n²)。
排序稳定。
(3)希尔排序基本原理:希尔排序也一种插入排序类的方法,由于直接插入排序序列越短越好,源序列的排序度越好效率越高。
Shell 根据这两点分析结果进行了改进,将待排记录序列以一定的增量间隔dk 分割成多个子序列,对每个子序列分别进行一趟直接插入排序, 然后逐步减小分组的步长dk,对于每一个步长dk 下的各个子序列进行同样方法的排序,直到步长为1 时再进行一次整体排序。
排序算法实验报告
数据结构实验报告八种排序算法实验报告一、实验内容编写关于八种排序算法的C语言程序,要求包含直接插入排序、希尔排序、简单项选择择排序、堆排序、冒泡排序、快速排序、归并排序和基数排序。
二、实验步骤各种内部排序算法的比较:1.八种排序算法的复杂度分析〔时间与空间〕。
2.八种排序算法的C语言编程实现。
3.八种排序算法的比较,包括比较次数、移动次数。
三、稳定性,时间复杂度和空间复杂度分析比较时间复杂度函数的情况:时间复杂度函数O(n)的增长情况所以对n较大的排序记录。
一般的选择都是时间复杂度为O(nlog2n)的排序方法。
时间复杂度来说:(1)平方阶(O(n2))排序各类简单排序:直接插入、直接选择和冒泡排序;(2)线性对数阶(O(nlog2n))排序快速排序、堆排序和归并排序;(3)O(n1+§))排序,§是介于0和1之间的常数。
希尔排序(4)线性阶(O(n))排序基数排序,此外还有桶、箱排序。
说明:当原表有序或基本有序时,直接插入排序和冒泡排序将大大减少比较次数和移动记录的次数,时间复杂度可降至O〔n〕;而快速排序则相反,当原表基本有序时,将蜕化为冒泡排序,时间复杂度提高为O〔n2〕;原表是否有序,对简单项选择择排序、堆排序、归并排序和基数排序的时间复杂度影响不大。
稳定性:排序算法的稳定性:假设待排序的序列中,存在多个具有相同关键字的记录,经过排序,这些记录的相对次序保持不变,则称该算法是稳定的;假设经排序后,记录的相对次序发生了改变,则称该算法是不稳定的。
稳定性的好处:排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。
基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。
另外,如果排序算法稳定,可以防止多余的比较;稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序四、设计细节排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
数据结构实验报告排序
数据结构实验报告排序数据结构实验报告:排序引言:排序是计算机科学中常见的算法问题之一,它的目标是将一组无序的数据按照特定的规则进行排列,以便于后续的查找、统计和分析。
在本次实验中,我们将学习和实现几种常见的排序算法,并对它们的性能进行比较和分析。
一、冒泡排序冒泡排序是最简单的排序算法之一,它通过不断交换相邻的元素,将较大(或较小)的元素逐渐“冒泡”到数组的一端。
具体实现时,我们可以使用两层循环来比较和交换元素,直到整个数组有序。
二、插入排序插入排序的思想是将数组分为两个部分:已排序部分和未排序部分。
每次从未排序部分中取出一个元素,插入到已排序部分的适当位置,以保持已排序部分的有序性。
插入排序的实现可以使用一层循环和适当的元素交换。
三、选择排序选择排序每次从未排序部分中选择最小(或最大)的元素,与未排序部分的第一个元素进行交换。
通过不断选择最小(或最大)的元素,将其放置到已排序部分的末尾,从而逐渐形成有序序列。
四、快速排序快速排序是一种分治的排序算法,它通过选择一个基准元素,将数组划分为两个子数组,其中一个子数组的所有元素都小于等于基准元素,另一个子数组的所有元素都大于基准元素。
然后对两个子数组分别递归地进行快速排序,最终将整个数组排序。
五、归并排序归并排序也是一种分治的排序算法,它将数组划分为多个子数组,对每个子数组进行排序,然后再将排好序的子数组合并成一个有序的数组。
归并排序的实现可以使用递归或迭代的方式。
六、性能比较与分析在本次实验中,我们对以上几种排序算法进行了实现,并通过对不同规模的随机数组进行排序,比较了它们的性能。
我们使用了计算排序时间的方式,并记录了每种算法在不同规模下的运行时间。
通过对比实验结果,我们可以得出以下结论:1. 冒泡排序和插入排序在处理小规模数据时表现较好,但在处理大规模数据时性能较差,因为它们的时间复杂度为O(n^2)。
2. 选择排序的时间复杂度也为O(n^2),与冒泡排序和插入排序相似,但相对而言,选择排序的性能稍好一些。
知识点归并排序和基数排序
数据结构
二、空间性能 指的是排序过程中所需的辅助空间大小
1. 所有的简单排序方法(包括:直接插入、
起泡和简单选择) 和堆排序的空间复杂度为O(1);
2. 快速排序为O(logn),为递归程序执行过程中,
栈所需的辅助空间;
数据结构
容易看出,对 n 个记录进行归并排序的时间 复杂度为Ο(nlogn)。即:
每一趟归并的时间复杂度为 O(n), 总共需进行 log2n 趟。
数据结构
10.6 基 数 排 序
数据结构
基数排序是一种借助“多关键字排序” 的思想来实现“单关键字排序”的内部 排序算法。
多关键字的排序
链式基数排序
一、多关键字的排序 n 个记录的序列 { R1, R2, …,Rn} 对关键字 (Ki0, Ki1,…,Kid-1) 有序是指:
对于序列中任意两个记录 Ri 和 Rj (1≤i<j≤n) 都满足下列(词典)有序关系: (Ki0, Ki1, …,Kid-1) < (Kj0, Kj1, …,Kjd-1) 其中: K0 被称为 “最主”位关键字
数据结构
10.5 归 并 排 序(知识点三)
数据结构
归并的含义是将两个或两个以上的有序表组 合成一个新的有序表。
归并排序可分为两路归并排序,或多路归并 排序,既可用于内排序,也可用于外排序。这 里仅对内排序的两路归并方法进行讨论。
数据结构
两路归并排序算法思路:
假设初始序列含有n个记录,首先把n个记录 看成n个长度为1的有序序列,进行两两归并, 得到 n/2个长度为2的关键字有序序列, 再两两归并直到所有记录归并成一个长度为n 的有序序列为止。
归并排序-PPT优秀课件
堆排序
O(1)
归并排序
O(n)
空间复杂度
30
排序方法 直接插入排序 希尔排序 冒泡排序 快速排序 简单选择排序 堆排序 归并排序
辅助空间
稳定 不稳定 稳定 不稳定 稳定 不稳定 稳定
算法稳定性
31
10.6 内部排序方法的比较讨论
❖ 简单性
一类是简单算法,包括直接插入排序、直接 选择排序和冒泡排序,
另一类是改进后的算法,包括希尔排序、堆 排序、快速排序和归并排序,这些算法较复杂
32
10.6 内部排序方法的比较讨论
❖ 待排序记录个数比较
n越小,采用简单排序方法越合适。 n越大,采用改进的排序方法越合适。
因为n越小,O(n2)同O(nlog2n)的差距越小, 并且输入和调试简单算法比 高效算法要容易
关键码的分布情况29排序方法平均情况最好情况最坏情况时间复杂度30排序方法辅助空间空间复杂度31排序方法辅助空间稳定算法稳定性32简单性一类是简单算法包括直接插入排序直接选择排序和冒泡排序另一类是改进后的算法包括希尔排序堆排序快速排序和归并排序这些算法较复杂106内部排序方法的比较讨论33106内部排序方法的比较讨论待排序记录个数比较n越小采用简单排序方法越合适
33
10.6 内部排序方法的比较讨论
❖ 数据的信息量比较
信息量越大,移动记录所花费的时间就越多, 所以对记录的移动次数较多的算法不利。
排序方法
直接插入排序 冒泡排序
直接选择排序
最好情况 O(n) 0 0
最坏情况 O(n2) O(n2) O(n)
平均情况 O(n2) O(n2) O(n)
34
10.6 内部排序方法的比较讨论
❖ 数据的分布情况比较
算法实验报告_排序
一、实验背景排序是计算机科学中常见的基本操作,对于数据结构的学习和运用具有重要意义。
本实验旨在通过实现几种常见的排序算法,比较它们的性能,并分析它们的适用场景。
二、实验目的1. 熟悉几种常见的排序算法。
2. 比较不同排序算法的执行时间和稳定性。
3. 分析不同排序算法的适用场景。
三、实验内容1. 选择排序算法:冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。
2. 实现排序算法。
3. 生成随机数组和有序数组,分别对两种数组进行排序。
4. 记录每种排序算法的执行时间和稳定性。
5. 分析不同排序算法的性能。
四、实验步骤1. 实现排序算法(1)冒泡排序冒泡排序是一种简单的排序算法,它重复地遍历待排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。
```pythondef bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]```(2)选择排序选择排序是一种简单直观的排序算法。
它的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
以此类推,直到所有元素均排序完毕。
```pythondef selection_sort(arr):n = len(arr)for i in range(n):min_idx = ifor j in range(i+1, n):if arr[min_idx] > arr[j]:min_idx = jarr[i], arr[min_idx] = arr[min_idx], arr[i]```(3)插入排序插入排序是一种简单直观的排序算法。
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
数据库系统实现两阶段多路归并排序算法的C实现
两阶段多路归并排序Two-Phase Multiway Merge-Sort实验报告目录1 实验目的 (3)2 实验内容 (3)3 实验环境 (3)4 实验的设计和实现 (3)4.1 算法描述 (3)4.2 设计思路 (4)4.3 数据结构 (5)4.4 具体实现 (6)5 实验结果 (9)5.1 50MB内存TPMMS实验结果 (9)5.2 10MB内存TPMMS实验结果 (9)5.3 100MB内存TPMMS实验结果 (10)5.4 三者的比较 (11)6 实验遇到的问题和解决方法 (11)6.1 Phase2阶段遇到的问题和解决方法 (11)6.2 生成子记录文件名的方法 (13)7 代码附录 (13)1实验目的通过merge-sort算法的实现,掌握外存算法所基于的I/O模型与内存算法基于的RAM模型的区别;理解不同的磁盘访问优化方法是如何提高数据访问性能的。
2实验内容生成一个具有10,000,000个记录的文本文件,其中每个记录由100个字节组成。
实验只考虑记录的一个属性A,假定A为整数类型。
记录在block上封装时,采用non-spanned方式,即块上小于一个记录的空间不使用。
Block的大小可在自己的操作系统上查看,xp一般为4096 bytes。
在内存分配50M字节的空间用于外部merge-sort。
要求设计和实现程序完成下列功能:1)生成文本文件,其中属性A的值随机产生。
2)按照ppt中的方法对文本文件中的记录,按照属性A进行排序,其中在第二阶段的排序中每个子列表使用一个block大小的缓冲区缓冲数据。
3)按照教材cylinder-based buffers(1M bytes)的方法,修改第二阶段的算法。
4)比较两种方法的时间性能,如果有更大的内存空间,算法性能还能提高多少?3实验环境1)Visual C++ 6.02)Windows 7操作系统4实验的设计和实现4.1算法描述Two-Phase Multiway Merge-Sort算法的具体描述分为2个阶段,如下所示:●Phase 11)Fill main memory with records.2)Sort with favorite main memory sorting algorithms.3)Write sorted list to disk.4)Repeat until all records have been put into one of the sorted lists.●Phase 21)Initially load input buffers with the first block of their respective sortedlists.2)Repeated run a competition among the first unchosen records of each ofthe buffered blocks.3)If an input block is exhausted, get the next block from the same file.4)If the output block is full, write it to disk.4.2设计思路从上述的算法描述中,我们知道,系统主要由2大模块组成:Phase1和Phase2。
归并排序算法图文详解(模版使用)
归并排序算法图⽂详解(模版使⽤)算法介绍引⽤百度百科的介绍。
归并排序(Merge Sort)是建⽴在操作上的⼀种有效,稳定的排序算法,该算法是采⽤(Divide and Conquer)的⼀个⾮常典型的应⽤。
将已有序的⼦合并,得到完全有序的序列;即先使每个⼦序列有序,再使⼦序列段间有序。
若将两个有序表合并成⼀个有序表,称为⼆路归并。
算法描述归并排序,采⽤是分治法,先将数组分成⼦序列,让⼦序列有序,再将⼦序列间有序,合并成有序数组。
算法描述:(1)把长度为n的输⼊序列分成长度 n/2的⼦序列;(2)对两个⼦序列采⽤归并排序;(3)合并所有⼦序列。
算法实现void mergeSortInOrder(int[] arr,int bgn,int mid, int end){int l = bgn, m = mid +1, e = end;//相当于对⼀个数组的前半部分和后半部分进⾏排序排序,从开始的只有两个数,到后⾯//因为基本有序,所以只需要进⾏合并就⾏int[] arrs = new int[end - bgn + 1];int k = 0;//进⾏有序合并while(l <= mid && m <= e){if(arr[l] < arr[m]){arrs[k++] = arr[l++];}else{arrs[k++] = arr[m++];}}//如果前半部分⼤的⽐较多,直接接在后⾯while(l <= mid){arrs[k++] = arr[l++];}//如果后半部分⼤的⽐较多,直接接在后⾯while(m <= e){arrs[k++] = arr[m++];}//对我们原来的数组进⾏值的覆盖for(int i = 0; i < arrs.length; i++){arr[i + bgn] = arrs[i];}}void mergeSort(int[] arr, int bgn, int end){//如果开始指针⼤于结束指针,结束if(bgn >= end){return;}//通过分治将我们的数组分成多个⼩数组int mid = (bgn + end) >> 1;mergeSort(arr,bgn,mid);mergeSort(arr,mid + 1, end);//对我们的⼩数组进⾏排序mergeSortInOrder(arr,bgn,mid,end);}算法分析稳定排序外排序(需要消耗额外的内存)时间复杂度O(nlogn),空间复杂度为O(1)。
大数据数据结构和算法_排序_归并排序(外部排序)
2.利用多路归并排序对这些小文件排序,按行写入最终的有序大 文件.
同
最终结果, 大文件(有序)
排序
2
6
1
3
7
5
4
7
13
5
8
14
6
20
15
文件1 文件2 文件3
3个小文件,每个文件内的数 据都有序
6 6 13
将最小值写入
6
6 13
将最小值写入
6
7 13
将最小值写入
7
7 13
将最小值写入
7
8 13
将最小值写入
8
13 20
将最小值写入
13
14 20
将最小值写入
14
15 20
排序
外部排序合并策略 维护n个小文件的输入input[n]. 维护1个内存中的小对象或者小数组mem_array[n],用于排序. 1.每次从小对象mem_array中取最小least的元素,写入最终文件, 一次写入一个数据. 2.若选取的最小元素属于第 i 个小文件,那么从input[i]读取下一 个数据放入mem_array[i]中,进行排序. 3.重复1、2步,直到所有的input[n]中数据都已处理完毕.
排序
最小值属于哪个文件,就从哪个文件取下一个值 并加入mem进行排序
2
6
1
1
2
6
将最小值写入
1
3
7
5
4
7
13
5
8
14
6
20
15
文件1 文件2 文件3
2
5
数据结构排序实验报告
引言概述:数据结构排序实验是计算机科学与技术专业中一项重要的实践课程。
通过实验,可以深入理解和掌握不同排序算法的原理、特点和性能表现。
本文将针对数据结构排序实验进行详细的阐述和总结,包括实验目的、实验内容、实验结果分析和总结。
一、实验目的1. 加深对数据结构排序算法的理解:通过实验,掌握不同排序算法的工作原理和实现方式。
2. 分析和比较不同排序算法的性能:对比不同排序算法在不同数据规模下的时间复杂度和空间复杂度,理解它们的优劣势。
3. 提高编程和算法设计能力:通过实验的编写,提升对排序算法的实现能力和代码质量。
二、实验内容1. 选择排序算法:选择排序是一种简单直观的排序算法,将序列分为有序和无序两部分,每次从无序部分选择最小(最大)元素,放到有序部分的末尾(开头)。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析2. 插入排序算法:插入排序逐步构建有序序列,对于未排序的元素,在已排序序列中从后向前扫描,找到对应位置插入。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析3. 快速排序算法:快速排序利用分治的思想,将序列分为左右两部分,选取基准元素,将小于基准的放在左边,大于基准的放在右边,递归地对左右部分进行排序。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析4. 归并排序算法:归并排序是一种稳定的排序算法,通过将序列分为若干子序列,分别进行排序,然后再将排好序的子序列合并成整体有序序列。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析5. 堆排序算法:堆是一种特殊的树状数据结构,堆排序利用堆的性质进行排序,通过构建大顶堆或小顶堆,并逐个将堆顶元素移出形成有序序列。
- 算法原理及步骤- 实现过程中的注意事项- 时间复杂度和空间复杂度的分析三、实验结果分析1. 比较不同排序算法的执行时间:根据实验数据和分析,对比不同排序算法在不同数据规模下的执行时间,并针对其时间复杂度进行验证和分析。
归并排序算法实现归并排序的原理和时间复杂度分析
归并排序算法实现归并排序的原理和时间复杂度分析归并排序是一种经典的排序算法,它采用分治策略来解决排序问题。
它的原理是将一个数组分成两个子数组,然后对每个子数组进行排序,最后再合并两个已排序的子数组。
根据分治的思想,我们可以递归地将问题分解为较小的子问题,通过解决子问题并将结果合并来解决原始问题。
1. 归并排序的原理归并排序的原理可以分为三个步骤:分解、解决和合并。
(1) 分解:首先,将待排序的数组分解为两个子数组,直到每个子数组的长度为1。
例如,对于数组[5, 2, 7, 1],我们将其分解为[5, 2]和[7, 1]两个子数组。
(2) 解决:接下来,对每个子数组递归地应用归并排序算法,直到子数组的长度为1为止。
递归的终止条件是数组长度为1时,这时数组就是有序的。
对于[5, 2]和[7, 1]两个子数组,我们将其分别排序得到[2, 5]和[1, 7]。
(3) 合并:最后,将两个已排序的子数组合并成一个有序的数组。
合并过程中,我们比较两个子数组的第一个元素,将较小的元素放入结果数组,并移动指针,直到一个子数组已经全部放入结果数组中,然后将另一个子数组中的剩余元素放入结果数组。
对于[2, 5]和[1, 7]两个已排序的子数组,我们将其合并得到最终的排序结果[1, 2, 5, 7]。
通过不断地分解、解决和合并的步骤,归并排序算法最终能够对整个数组进行排序。
2. 时间复杂度分析归并排序算法的时间复杂度可以通过递推关系式来分析。
假设待排序的数组长度为n,则归并排序的时间复杂度可以表示为T(n)。
(1) 分解:每次分解过程将数组划分为两个子数组,所以分解过程的时间复杂度为O(log n)。
其中,log n表示以2为底n的对数。
(2) 解决:对每个子数组的解决过程需要的时间复杂度为O(n)。
因为每个子数组的长度为n/2,所以花费的时间为O(n/2)。
递归地应用归并排序算法,最后得到的时间复杂度为O(n)。
(3) 合并:在合并过程中,我们需要比较每个元素并放入结果数组中,所以合并过程的时间复杂度为O(n)。
数据结构排序实验报告
数据结构排序实验报告一、实验目的本次数据结构排序实验的主要目的是深入理解和掌握常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序和归并排序,并通过实际编程和实验分析,比较它们在不同规模数据下的性能表现,从而为实际应用中选择合适的排序算法提供依据。
二、实验环境本次实验使用的编程语言为 Python 3x,开发环境为 PyCharm。
实验中使用的操作系统为 Windows 10。
三、实验原理1、冒泡排序(Bubble Sort)冒泡排序是一种简单的排序算法。
它重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。
2、插入排序(Insertion Sort)插入排序是一种简单直观的排序算法。
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,直到整个数组有序。
3、选择排序(Selection Sort)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
以此类推,直到所有元素均排序完毕。
4、快速排序(Quick Sort)通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
5、归并排序(Merge Sort)归并排序是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
四、实验步骤1、算法实现使用 Python 语言分别实现上述五种排序算法。
为每个算法编写独立的函数,函数输入为待排序的列表,输出为排序后的列表。
2、生成测试数据生成不同规模(例如 100、500、1000、5000、10000 个元素)的随机整数列表作为测试数据。
数据结构课程设计--二路归并排序说明书
前言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),同时在处理大规模归并排序的时候,排序速度也明显优于冒泡法等一些排序算法,提高排序算法的效率。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
大连理工大学实验预习报告
学院(系):电信专业:班级:
姓名:学号:组:___
实验时间:实验室:实验台:
指导教师签字:成绩:
实验名称Merge sort
一、实验目的和要求
(一)、实验目的
Design the merge sort algorithm and implement it in C language
设计归并排序算法并于C语言实现。
(二)、实验要求
Requirements:
1) Analyze the time complexity of your algorithm
2) Submit the document explaining your algorithm as well as the source code.
要求:
1)分析算法的时间复杂度。
2) 提交的文档中说明你的算法和源代码。
二、实验原理
归并排序是建立在归并操作上的一种有效的排序算法。
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
首先考虑下如何将将二个有序数列合并。
这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。
然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可
解决了上面的合并有序数列问题,再来看归并排序,其的基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。
如何让这二组组内数据有序了?
可以将A,B组各自再分成二组。
依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。
这样通过先递归的分解数列,再合并数列就完成了归并排序。
大连理工大学实验报告
学院(系):电信专业:电创班级:1501
姓名:陈晓牛津学号:201588011 组:___
实验时间:2017/4/18 实验室:实验台:
指导教师签字:成绩:
实验名称Mergesort
一、算法分析
归并组合
功能:
用二分检索查找的方法采用从低部分,高部分进行查找建立一个新的数组,将小的数放入新的数组中。
归并排序
功能;利用递归进行排序,先查找中点位置,再对前部分查找,然后后部分,将小的数据放入新的数组
二、关键代码及注释
void mergesort(int *a,intleft,int right)
{
int mid;
if(left < right) /* 分组条件*/
{
mid = (left + right)/2; /* 取中点*/
mergesort(a,left,mid); /* 左边分组*/
mergesort(a,mid+1,right); /* 右边分组*/
partition(left,mid,right); /* 归并函数*/
}
三、运行结果
四、代码
#include<stdio.h>
inta[]={70,66,88,70,45,90,33,66,70,22,11,90,11,90,11,90},k = 0; inti;
void mergesort(int *a, int left, int right);
void partition(int left, int mid, int right);
intmain()
{
printf("要排序的数组为:\n"); /* 输出要排序的数*/
for(i = 0; a[i] != NULL; i++)
{
printf("%4d",a[i]);
}
printf("\n");
mergesort(a,0,15); /* 归并排序*/
printf("则结果为:\n");
for(i = 0; a[i] != NULL; i++) /* 经过排序之后输出数组a */ {
printf("%4d",a[i]);
}
printf("\n");
}
void mergesort(int *a,intleft,int right)
{
int mid;
if(left < right) /* 分组条件*/
{
mid = (left + right)/2; /* 取中点*/
mergesort(a,left,mid); /* 左边分组*/
mergesort(a,mid+1,right); /* 右边分组*/
partition(left,mid,right); /* 归并函数*/
}
}
void partition(intleft,intmid,int right) /* 归并的函数定义*/
{
int h = 0, l = left, m = mid + 1, j = 0,b[20]; /* 定义变量为了保证a左右下标不改变,b作为辅助数组,存放归并的后的元素*/
while(right >= m && l < mid+1) /* 终止条件为数组元素用尽*/
{
if(a[l] < a[m]) /* 如果左边的小,则将左边的元素赋值给b */
{
b[h++] = a[l++];
}
else /* 否则将右边元素赋值给b */
{
b[h++] = a[m++];
}
}
if(right < m) /* 如果右边的元素用完,则将左边的元素全部赋值给数组b,完成一趟排序*/
{
for(; l <= mid; l++)
{
b[h++] = a[l];
}
}
else if(l > mid) /* 如果是左边的用完,则同理将右边的全部赋值给数组b */
{
for(; m <= right; m++)
{
b[h++] = a[m];
}
}
for(; left <= right; left++) /* 完成归并,将数组b复制给数组a, 控制变量尤为重要*/ {
a[left] = b[j++];
}
printf("第%d次比较:\n",++k); /* 实现计数功能*/
for(i = 0; a[i] != NULL; i++) /* 每次归并输出a查看排序的进度*/
{
printf("%4d",a[i]);
}
printf("\n");
}。