码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-05-15 01:21:21      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:算法   排序算法   归并排序   

归并排序是将排好序的序列逐步合成一个大序列的算法,从字面上来分析,主要分为归并和排序。

算法描述:

1.申请一块空间,大小为两个排好序序列长度之和,用来存放归并后的序列。

2.设两个指针,分别指向两个已经排好序的序列的起始地址。

3.比较两个指针指向位置的值大小,根据升序降序,选择较小值或者较大值存储在合并空间内,并将相应指针后移。

4.重复3操作,直至指针移至序列尾部。

5.将另一个序列的值全部合并至合并序列中。


先抛开描述,说说自己的理解,就是把一个短有序序列合并成一个新的长有序序列,就是它的主体意思了。一个有序的序列最简单的就是它只有一个元素的序列,它必然有序。两个只有一个元素的序列合并,当然就可以看做是两个有序序列的合并了。依次类推,直至将所有的元素合并到一个序列,排序完成。这里很明显的是需要使用递归的。因为我们将一个大问题分成若干个小问题,自然就想到了分治。

先看看合并:

    public int[] merge(int[] a, int[] b){
        int[] array = new int[a.length + b.length];
        
        int i = 0;
        int j = 0;
        int k = 0;
        while ((i < a.length) && (i < b.length)){
            if (a[i] < b[i]){
                array[k++] = a[i];
                i++;
            }else {
                array[k++] = b[j];
                j++;
            }
        }
        
        while (i < a.length){
            array[k++] = a[i++];
        }
        
        while (j < b.length){
            array[k++] = b[j++];
        }
        return array;
    }

算法简单也比较很高效,时间复杂度处于O(n)级别,再来看看排序,比较麻烦一点的就是讲数组划分成一个个的元素了。其实它也不难:

    if (left < right){
            int haft = (left + right)/2;
            mergeSort(arr, tmp, left, haft);
            mergeSort(arr, tmp, haft + 1, right);
           //操作
           .....
     }
如此,当划分到最后一层就剩下一个元素。再依次返回,就可以得到我们想要的代码了。

    public static <T extends Comparable<? super T>> void mergeSort(
            T[] arr, T[] tmp, int left, int right){
        if (left < right){
            int haft = (left + right)/2;
            mergeSort(arr, tmp, left, haft);
            mergeSort(arr, tmp, haft + 1, right);
            merge(arr, tmp,left,  haft + 1, right);
        }
    }

    public static <T extends  Comparable<? super T>> void merge(
            T[] arr, T[] tmp, int lPos, int rPos, int rEnd){
        int lEnd = rPos - 1;
        int tPos = 0;
        while ((lPos <= lEnd) && (rPos <= rEnd)){
            if (arr[lPos].compareTo(arr[rPos]) >= 0){
                tmp[tPos++] = arr[lPos++];
            }else {
                tmp[tPos++] = arr[rPos++];
            }
        }

        while (lPos <= lEnd){
            tmp[tPos++] = arr[lPos++];
        }

        while (rPos <= rEnd){
            tmp[tPos++] = arr[rPos++];
        }

        tPos -= 1;
        for (int i = 0; tPos >= 0; i++){
            arr[rEnd - i] = tmp[tPos--];
        }

    }

时间复杂度可以算出 O(N) * O(logN) = O(N*logN)。空间复杂度其实并不高,我们只利用一个长度为N 的tmp数组,再无其他辅助空间了。总体看来,无论从空间复杂度还是时间复杂度来说,它都是同高效的。

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

标签:算法   排序算法   归并排序   

原文地址:http://blog.csdn.net/u010233260/article/details/45727165

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!