归并排序

归并排序

    归并排序以O(NlogN)的最坏运行时间运行, 所比较的次数几乎是最优的。它是递归算法的一个好的例子。
    这个算法中基本操作是合并两个已排序的表。因为这两个表是已排序的, 所以若将输出放到第三个表中,则该算法可以通过对输入数据一趟排序来完成。基本的合并算法是取两个输入数组A和B, 一个输出数组C, 以及三个计数器Actr、Bctr、Cctr,他们初始置于对应数组的开始端。A[Actr]和B[Bctr]中的较小者被拷贝到C中下一个位置, 相关的计数器向前推进一步。当两个输入表中有一个用完的时候, 则将另一个表剩余的数拷贝到C组。


例子:已知一个数组 24, 13, 26, 1, 2, 27, 38, 15
这里写图片描述

    合并两个已排序的表时间显然是线性时间, 因为最多进行N-1次比较,其中N是元素的总数。为了看清这一点, 注意每次比较都把一个元素添加到C中, 但最后的比较除外。

    而归并排序的策略是将一个一整块的表分割成二块表,然后再细分,
这就是典型的分治(divide-and-conquer)策略, 他将问题分成小问题然后递归求解。

package sort;

/*
 * 归并排序:
 *          归并排序以0(NlogN)最坏情形时间运行而所使用的比较次数几乎是最优的。
 * 
 * 基本操作:是合并两个已排序的表。因为这两个表已排序
 */
public class Mesgesort<AnyType>{


    private static <AnyType extends Comparable<? super AnyType>> 
    void mergeSort(AnyType[] a, AnyType[] tmpArray, int left, int right){
        if(left < right){
            int center = (left + right) / 2;
            mergeSort(a, tmpArray, left, center);
            mergeSort(a, tmpArray, center + 1, right);
            merge(a, tmpArray, left, center + 1, right);
        }
    }

    //驱动程序
    public static <AnyType extends Comparable<? super AnyType>> void mergeSort(AnyType[] a){
        @SuppressWarnings("unchecked")
        AnyType[] tmpArray = (AnyType[])new Comparable[a.length];
        mergeSort(a, tmpArray, 0, a.length - 1);
    }

    private static <AnyType extends Comparable<? super AnyType>> void merge(AnyType[] a, AnyType[] tmp, int leftPos, int rightPos, int rightEnd){
        int leftEnd = rightPos - 1;
        int tmpPos = leftPos;   //从起点开始
        int numElement = rightEnd + 1;

        while(leftPos <= leftEnd && rightPos <= rightEnd)
            if(a[leftPos].compareTo(a[rightPos]) <= 0)
                tmp[tmpPos++] = a[leftPos++];
            else
                tmp[tmpPos++] = a[rightPos++];

        //如果左边还有的话, 那么就把左边的都加到后面
        while(leftPos <= leftEnd)
            tmp[tmpPos++] = a[leftPos++];
        //如果右边还有剩余的话, 那么就把右边的都加到后面
        while(rightPos <= rightEnd)
            tmp[tmpPos++] = a[rightPos++];
        System.out.println("第" + count++ + "次");
        for(int i = 0; i < numElement; i++, rightEnd--){
            a[rightEnd] = tmp[rightEnd];
            System.out.print(tmp[i] + " ");
        }
        System.out.println();
    }

    private static int count = 1;
    public static void main(String[] args){
        Integer[] a = new Integer[]{24, 13, 26, 1, 2, 27, 38, 15};
        mergeSort(a);
        for (Integer integer : a) {
            System.out.print(integer + " ");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值