排序——归并类排序

归并类排序是首先将原始无序序列划分成两个子序列,然后分别对每个子序列递归地进行排序,最后再将有序子序列合并。

归并排序是一种基于分治法的排序。

归并排序是简单地进行“分”,重点却在“合”的过程,即对两个有序子序列进行归并的过程:每次比较子序列头,取出较小的进入结果序列;其后继续比较两个子序列头,取出较小的进入结果序列,重复上述过程,直到其中一个子序列为空,剩余子序列中的元素就可以直接进入结果序列。

1. 归并排序

二路归并排序是首先将初始序列的 n 个记录看成是 n 个有序的子序列,每个子序列的长度为1.然后两两归并,得到 \left \lceil n/2 \right \rceil 个长度为 2 ( n 为奇数时,最后一个序列的长度为 1)的有序子序列。在此基础上,再对长度为 2 的有序子序列进行两两归并,得到若千个长度为 4 的有序子序列。以此类推,直到得到一个长度为 n 的有序序列为止。

(图片来源:http://www.cnblogs.com/jingmoxukong/p/4308823.html

1.1 代码实现

package com.zth.sort;

import java.util.Arrays;

/**
 * @author 时光·漫步
 * 二路归并排序
 */
public class MergeSort {
    public static void main(String[] args){
        Integer[] array = {3,2,5,8,4,7,6,9};
        mergeSort(array);

        System.out.println(Arrays.toString(array));
    }
    
    /**
     * 排序算法驱动程序
     */
    public static <AnyType extends Comparable<? super AnyType>>
    void mergeSort(AnyType[] array){
        // 临时辅助空间
        AnyType[] tmpArray = (AnyType[])new Comparable[array.length];
        mergeSort(array,tmpArray,0,array.length-1);
    }

    /**
     * 用于递归调用的内部方法
     * @param left 子序列的起始索引
     * @param right 子序列的终止索引
     */
    private static <AnyType extends Comparable<? super AnyType>>
    void mergeSort(AnyType[] array,AnyType[] tmpArray,int left,int right){
        if(left < right){
            int center = (left + right)/2;
            mergeSort(array,tmpArray,left,center);
            mergeSort(array,tmpArray,center+1,right);
            merge(array,tmpArray,left,center+1,right);
        }
    }

    /**
     *合并相邻两个有序子序列
     * @param leftpos 第一个子序列的起始索引
     * @param rightpos 第二个子序列的起始索引
     * @param rightEnd 第二个子序列的终止索引
     */
    private static <AnyType extends Comparable<? super AnyType>>
    void merge(AnyType[] array,AnyType[] tmpArray,int leftpos,int rightpos,int rightEnd){
        int leftEnd = rightpos -1;
        int tmpPos = leftpos;
        int numElements = rightEnd - leftpos+1;

        // 两个子序列都不为空时
        while (leftpos <= leftEnd && rightpos <= rightEnd){
            if (array[leftpos].compareTo(array[rightpos]) <= 0 ){
                tmpArray[tmpPos++] = array[leftpos++];
            }else {
                tmpArray[tmpPos++] = array[rightpos++];
            }
        }

        // copy rest of the first subarray
        while (leftpos <= leftEnd){
            tmpArray[tmpPos++] = array[leftpos++];
        }

        // copy rest of the second subarray
        while (rightpos <= rightEnd){
            tmpArray[tmpPos++] = array[rightpos++];
        }

        // copy tmpArray back
        for (int i = 0; i < numElements; i++,rightEnd--) {
            array[rightEnd] = tmpArray[rightEnd];
        }
    }

}

1.2 性能分析

时间复杂度空间复杂度稳定性
平均情况最坏情况最好情况
O( N log N)O( N log N)O( N log N)o(N)稳定

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值