排序算法--归并排序(merge)

 归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为:

1)划分子表   2)合并半子表

时间复杂度是Θ(nlgn),优于插入排序算法。

算法描述
    1) 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
    2) 设定两个指针,最初位置分别为两个已经排序序列的起始位置
    3) 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
    4) 重复步骤3直到某一指针达到序列尾
    5) 将另一序列剩下的所有元素直接复制到合并序列尾
    特点:归并排序是稳定的排序.即相等的元素的顺序不会改变,  速度仅次于快速排序,但较稳定。

  算法实现:

 1 //merge-sort
 2 void merge(int *arry,const int first,const int mid,const int last)
 3 {
 4     int i,index;
 5     int first1,last1;
 6     int first2,last2;
 7     int *tmp;
 8     tmp=(int*)malloc((last-first+1)*sizeof(int));
 9     if (tmp==NULL)
10         return ;
11     first1=first;
12     last1=mid;
13     first2=mid+1;
14     last2=last;
15     index=0;
16     while((first1<=last1)&&(first2<=last2))
17     {
18         if (arry[first1]<arry[first2])
19         {
20             tmp[index++]=arry[first1];
21             first1++;
22         }
23         else{
24             tmp[index++]=arry[first2];
25             first2++;
26         }
27     }
28     while(first1<=last1)
29     {
30         tmp[index++]=arry[first1++];
31     }
32     while(first2<=last2)
33     {
34         tmp[index++]=arry[first2++];
35     }
36     for (i=0;i<last-first+1;i++)
37     {
38         arry[first+i]=tmp[i];
39     }
40     free(tmp);
41 }
42
43 /*使用递归实现归并排序*/
44 void merge_sort(int *arry,const int first,const int last)
45 {
46     int mid=0;
47     if (first<last)
48     {
49         mid=(first+last)/2;
50         merge_sort(arry,first,mid);
51         merge_sort(arry,mid+1,last);
52         merge(arry,first,mid,last);
53     }
54 }

另附:实现方式使用迭代方式实现(个人感觉递归要代码好看一些)

 1 /*** 使用迭代实现 ***/
 2 void merge_sort(int *list, const int first, const int last)
 3 {
 4     int len= last-first+1;
 5     int left_min,left_max;
 6     int right_min,right_max;
 7     int index;
 8     int i;
 9     int *tmp;
10     tmp = (int *)malloc(sizeof(int)*len);
11     if( tmp == NULL || len <= 0 )
12         return;
13
14     for( i = 1; i < len; i *= 2 )
15     {
16         for( left_min = 0; left_min < len - i; left_min = right_max)
17         {
18             int j;
19             right_min = left_max = left_min + i;
20             right_max = left_max + i;
21             j = left_min;
22             if ( right_max > len )
23                 right_max = len;
24             index = 0;
25             while( left_min < left_max && right_min < right_max )
26             {
27                 tmp[index++] = (list[left_min] > list[right_min] ? list[right_min++] : list[left_min++]);
28             }
29             while( left_min < left_max )
30             {
31                 list[--right_min] = list[--left_max];
32             }
33             while( index > 0 )
34             {
35                 list[--right_min] = tmp[--index];
36             }
37             display_array(j,i*2,list+j);
38         }
39     }
40     free(tmp);
41 }

测试调用实例

 1 int main()
 2 {
 3     int arry[]={1,2,5,6,4,7};
 4     merge_sort(arry,0,5);
 5     for (int i=0;i<6;i++)
 6     {
 7         cout<<arry[i]<<" ";
 8     }
 9     system("pause");
10     return 0;
11 }

博客参考:http://blog.chinaunix.net/uid-24467128-id-2606195.html

     http://www.cnblogs.com/jillzhang/archive/2007/09/16/894936.html

时间: 2024-07-30 14:56:42

排序算法--归并排序(merge)的相关文章

经典排序算法 - 归并排序Merge sort

经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 4 1 5 9] 先看一下每一个步骤下的状态,完了再看合并细节 第一步 [6 2 4 1 5 9]原始状态 第二步 [2 6] [1 4] [5 9]两两合并排序,排序细节后边介绍 第三步 [1 2 4 6] [5 9]继续两组两组合并 第四步 [1 2 4 5 6 9]合并完成,排序完成 输出结

排序算法——归并排序

归并排序是分治法的典型举例. 分治法的思想是,将原有问题分解为几个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 分治模式在每层递归时都有三个步骤: 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例. 解决这些子问题,递归地求解各子问题.然而,若子问题的规模足够小,则直接求解. 合并这些子问题的解成原问题的解. 归并排序算法完全遵循分治模式.直观上其操作如下: 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列. 解决:使用

js 实现排序算法 -- 归并排序(Merge Sort)

原文: 十大经典排序算法(动图演示) 归并排序 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为2-路归并. 算法描述 把长度为n的输入序列分成两个长度为n/2的子序列: 对这两个子序列分别采用归并排序: 将两个排序好的子序列合并成一个最终的排序序列. 动图演示 代码实现 function merg

三种排序算法(归并排序、快速排序,堆排序)

归并排序:建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. 归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n)),算法不是自适应的,不需要对数据的随机读取. 工作原理: 1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后

(转)排序算法——归并排序与递归

基本思想 分析归并排序之前,我们先来了解一下分治算法. 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同.求出子问题的解,就可得到原问题的解. 分治算法的一般步骤: (1)分解,将要解决的问题划分成若干规模较小的同类问题: (2)求解,当子问题划分得足够小时,用较简单的方法解决: (3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解. 归并排序是分治算法的典型应用. 归并排序先将一个无序的N长数组切成N个有序子序列(只有一个数据的

经典排序算法---归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并 代码: void mergearray(struct SQ_LIST *v, int first, int mid, int last, int temp[]) { int i = first, j = mid + 1

第23章 排序算法(包括merge等)

  第23章 排序算法  Sorting:1 sort Sort elements in range (function template)2 stable_sort Sort elements preserving order of equivalents (function template)3 partial_sort Partially Sort elements in range (function template)4 partial_sort_copy Copy and parti

排序算法-归并排序(Java)

package com.rao.sort; import java.util.Arrays; /** * @author Srao * @className MergeSort * @date 2019/12/7 10:24 * @package com.rao.sort * @Description 归并排序 */public class MergeSort { /** * 归并排序:递归写法 * @param arr:要排序的数组 * @param left:数组最左边的元素的下标 * @p

Java排序算法——归并排序

基本思想归并排序利用分治法思想,先将一个序列分成一个个子序列,然后对子序列进行排序,再把有序子序列合并为整体有序序列. 两路归并排序算法思路:①把 n 个记录看成 n 个长度为1的有序子表:②进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表: ③重复第②步直到所有记录归并成一个长度为 n 的有序表为止. Java代码 import java.util.Arrays; public class MergeSort { public static int[] sort(int[]