二路归并排序算法

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
      归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

图解:

实现代码:

 1 #include <fstream>
 2 #include <iostream>
 3 #include <cstdio>
 4
 5 using namespace std;
 6
 7 const int N=100;
 8 int n,r[N],r1[N];
 9 void merge(int s,int m,int t);//将有序列[s,m]与[m+1,t]合并
10 void merge_sort(int s,int t);//将r[s,t]归并排序为r1[s,t]
11
12 int main()
13 {
14     //freopen("D:\\input.in","r",stdin);
15     //freopen("D:\\output.out","w",stdout);
16     scanf("%d",&n);
17     for(int i=1;i<=n;i++)
18         scanf("%d",&r[i]);
19     merge_sort(1,n);
20     for(int i=1;i<n;i++)
21         printf("%d ",r1[i]);
22     printf("%d\n",r1[n]);
23     return 0;
24 }
25 void merge(int s,int m,int t)
26 {
27     int i=s,j=m+1,k=s;
28     while(i<=m&&j<=t)
29     {
30         if(r[i]<r[j])   r1[k++]=r[i++];
31         else    r1[k++]=r[j++];
32     }
33     while(i<=m) r1[k++]=r[i++];
34     while(j<=t) r1[k++]=r[j++];
35     for(int e=s;e<=t;e++)
36         r[e]=r1[e];
37 }
38 void merge_sort(int s,int t)
39 {
40     if(s==t)    r1[s]=r[s];
41     else
42     {
43         int m=(s+t)/2;
44         merge_sort(s,m);
45         merge_sort(m+1,t);
46         merge(s,m,t);
47     }
48 }

时间: 2024-10-12 23:21:17

二路归并排序算法的相关文章

二路归并排序算法实现-完整C语言程序

/*********************************************************************************************** 1.设定两个指针,最初位置分别为两个已经排序序列的起始位置 2.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 3.重复步骤3直到某一指针达到序列尾 4.将另一序列剩下的所有元素直接复制到合并序列尾 归并排序: 归并排序具体工作原理如下(假设序列共有n个元素): 1.将序列

排序算法——二路归并排序

二路归并排序主要运用了"分治算法",分治算法就是将一个大的问题划分为n个规模较小而结构相似的子问题. 这些子问题解决的方法都是类似的,解决掉这些小的问题之后,归并子问题的结果,就得到了"大"问题的解. 二路归并排序主旨是"分解"与"归并". 下面是参考<高性能JavaScript>中的代码: function merge(left, right) { var result = []; while(left.leng

算法导论笔记(二)二路归并排序

二路归并排序 归并排序采用了一种”分而治之“的策略:将原问题分解成N个规模较小而结构与原问题相似的子问题:递归求解这些子问题,然后合并其结果,从而得到原问题的解. 分治模式一般遵循以下三个步骤: 分解(Divide):将原问题分解成若干子问题: 解决(Conquer):递归地求解各子问题.若子问题足够小,则直接求解: 合并(Combine):将子问题的解合并成原问题的解. ”二路归并"的算法也遵循以下三个步骤: 分解:将原序列中拥有的N个元素分解各含N / 2个元素的子序列: 解决:用合并排序法

排序算法大集锦_二路归并排序_2&3(分治思想)

第一段代码和合并排序差不多,用它来和第二段代码--二路归并排序作对比. 这一系列博客的特点就是--给出每趟排序的结果 本来想着好好写一下过程,弄个图片什么的,不过觉得网上的解析太多了,都比较好,所以这些博客就算是对自己的总结吧. #include <stdio.h> #include <limits.h> #include <malloc.h> void merge(int *m, int x, int y, int z) { int b1,b2,i,j,k; b1=y

排序算法之二路归并排序

基本思想 首先将待排序的元素序列分成两个长度相等的子序列,为每一个子序列排序,然后再将它们合并成一个序列. 代码 private void mergeSort(int[] a, int[] b, int left, int right) { if (left < right) { int middle = (left + right) / 2; mergeSort(a, b, left, middle); mergeSort(a, b, middle + 1, right); merge(a,

【数据结构与算法】二路归并排序

二路归并排序的时间复杂度是O(n*log2n),空间复杂度是O(n). 代码如下: /** * 源码名称:MergeSort.java * 日期:2014-08-11 * 程序功能:合并排序 * 版权:[email protected] * 作者:A2BGeek */ public class MergeSort { public void mergeSort(int[] in) { int length = in.length; int tmp[] = new int[length]; mer

算法之二路归并排序

public class SortTest { private static int ARRAY_NUMBER=10; public static void main(String[] args) { // TODO Auto-generated method stub //准备待排序的序列 Random random = new Random(); int[] array = new int[ARRAY_NUMBER]; for(int i = 0 ; i < array.length; i+

二路归并排序java实现

二路归并排序:其核心思想时将问题一分为二,并递归调用一分为二方法,使问题分割到不能再分各的原子问题,然后再归并,从实现原子问题开始,层层向上归并,最终解决整体问题.即所谓"分而治之,万流归一" 二路归并排序的时间复杂度计算如下: 参考资料:算法导论------递归算法的时间复杂度求解: 二路归并java实现: 1 public class MergeSort { 2 3 public static void main(String[] args) { 4 int [] array =

二路归并排序

package algrithm; import java.util.Scanner; public class Sort { public static void mergeSort(int a[], int l, int r) { if (l >= r) return; int mid=(l+r)/2; mergeSort(a, l, mid); mergeSort(a, mid+1, r); merge(a, l, mid, r); } //二路归并排序空间复杂度为O(n),时间复杂度为O