排序算法之二路归并排序

基本思想

首先将待排序的元素序列分成两个长度相等的子序列,为每一个子序列排序,然后再将它们合并成一个序列。

代码

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, b, left, middle, right);
    }
}

    private void merge(int[] a, int[] b, int left, int middle, int right) {
    if (left < right) {
        int p, q, t;
        p = left;
        q = middle + 1;
        t = left;
        while (p <= middle && q <= right) {
            if (a[p] <= a[q]) {
                b[t++] = a[p++];
            } else
                b[t++] = a[q++];
        }

        while (p <= middle)
            b[t++] = a[p++];
        while (q <= right)
            b[t++] = a[q++];

        for (int k = left; k < t; k++)
            a[k] = b[k];
    }
}

性能分析

  • 时间复杂度

    二路归并排序所需时间主要包括划分两个子序列的时间、两个子序列分别排序的时间和归并时间。划分子序列的时间是一个常熟,可以不考虑,最后的归并所需时间与元素个数n线性相关,因此,对于一个长度为n的元素序列进行归并排序的时间代价为T(n)=cn+2T(n/2)。由于归并排序不依赖于原待排序素元序列的初始输入排列,每次划分时两个子序列的长度基本一样,所以归并排序的最好、最差和平均时间复杂度都是O(nlog2n)。

  • 空间复杂度

    它需要一个与原待排序数组一样大的辅助空间。

  • 稳定性

    归并排序是一种稳定的排序算法。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 12:11:21

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

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

二路归并排序的时间复杂度是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

图解排序算法(四)之归并排序

基本思想 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之). 分而治之 可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现).分阶段可以理解为就是递归拆分子序列的过程,递归深度为log2n. 合并相邻有序子序列 再来看看治阶段

《算法导论》读书笔记之排序算法—Merge Sort 归并排序算法

自从打ACM以来也算是用归并排序了好久,现在就写一篇博客来介绍一下这个算法吧 :) 图片来自维基百科,显示了完整的归并排序过程.例如数组{38, 27, 43, 3, 9, 82, 10}. 在算法导论讲分治算法一章的时候提到了归并排序.首先,归并排序是一个分治算法. 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表, 即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列. merg() 函数是用来合并两个已有序的数组.  是整个算法的关键. 那么归并

算法之二路归并排序

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+

排序算法二:归并排序(Merge sort)

归并排序(Merge sort)用到了分治思想,即分-治-合三步,算法平均时间复杂度是o(nlgn). (一)算法实现 1 private void merge_sort(int[] array, int first, int last) { 2 if (first + 1 < last) { 3 int mid = (first + last) / 2; 4 merge_sort(array, first, mid); 5 merge_sort(array, mid, last); 6 7 /

常用算法之排序算法四【归并排序】

归并排序是将排好序的序列逐步合成一个大序列的算法,从字面上来分析,主要分为归并和排序. 算法描述: 1.申请一块空间,大小为两个排好序序列长度之和,用来存放归并后的序列. 2.设两个指针,分别指向两个已经排好序的序列的起始地址. 3.比较两个指针指向位置的值大小,根据升序降序,选择较小值或者较大值存储在合并空间内,并将相应指针后移. 4.重复3操作,直至指针移至序列尾部. 5.将另一个序列的值全部合并至合并序列中. 先抛开描述,说说自己的理解,就是把一个短有序序列合并成一个新的长有序序列,就是它

排序算法总结之归并排序

基本思想 设归并排序的当前区间是R[low..high],分治法的三个步骤是: ①分解:将当前区间一分为二,即求分裂点 ②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序: ③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]. 递归的终结条件:子区间长度为1(一个记录自然有序). 将两个有序序列合并成一个新的有序序列. ①把 n 个记录看成 n 个长度为 1的有序子表: ②进行两两归

排序算法入门之归并排序(java实现)

归并排序是采用分治法的典型应用. 参考<数据结构与算法分析-Java语言描述> 归并排序其实要做两件事: (1)"分解"--将序列每次折半划分. (2)"合并"--合并两个已排序的表. 合并:对于两个输入数组A和B,一个输出数组C,以及3个计数器Actr.Bctr.Cctr,他们的初始置于对应数组的开始端.A[Actr]和B[Bctr]中较小的拷贝到C中的下一个位置,相关的计数器向前推进一步.当两个输入表有一个用完时,则将另一个表中剩余的部分拷贝到C中.

排序算法学习之归并排序

1. 归并排序原理:有长度为n的子序列a[n],可以将其看做n个长度为1的子序列,将相邻子序列两两归并后子序列数量减少一半,再对子序列进行两两归并,数量又减少一般,重复直到得到一个长度为n的子序列 2. 实现归并操作的代码如下: /*array[s-m]和array[m+1-t]均已各自有序,合并使得array[s-t]有序*/ void Merge(int s, int m, int t, int *array) { int temp[t-s+1];/*设临时数组存放排序后的元素*/ int