java 实现归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。

归并操作的工作原理如下:

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置

第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

重复步骤3直到某一指针超出序列尾

将另一序列剩下的所有元素直接复制到合并序列尾。

具体工作原理如下(假设序列共有n个元素):

1.将序列每相邻两个数字进行归并操作(merge),形成floor(n/2+n%2)个序列,排序后每个序列包含两个元素

2.将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素

重复步骤2,直到所有元素排序完毕。

package com.test;

public class MergeSort {

    /**
     * @param source 源数组
     * @param temp 临时数据
     * @param start 起始索引
     * @param middle 索引的中间值
     * @param end 结束索引
     */
    public static void merge(int[] source,int[] temp,int start,int middle,int end){

        int i = start;
        int k = start;
        int j = middle+1;
        while(i!= middle+1 && j !=end+1){
            if(source[i] > source[j]){
                temp[k++] =source[j++];
            }else{
                temp[k++] = source[i++];
            }
        }
        //其中一半的数据已全部放入临时数组中,就将余下的数据,放到临时数组中,使用两组判断,每次调用只执行一个。
        while(i != middle+1){

            temp[k++] = source[i++];
        }

        while(j != end+1){
            temp[k++] = source[j++];
        }
        //将临时数组的数据赋值到原始数组。
        for ( i = start; i <= end ; i++) {

            source[i] = temp[i];
        }
    }

    /**
     * 递归实现归并
     * @param source 源数组
     * @param temp 临时数组
     * @param start 起始索引
     * @param end 结束索引
     */
    public static void mergeSort(int[] source,int[] temp,int start,int end){
        int middle;
        if (start < end){
            middle = start + (end-start)/2;
            mergeSort(source,temp,start,middle);
            mergeSort(source,temp,middle+1,end);
            merge(source,temp,start,middle,end);
        }
    }

    public static void main(String[] args) {
        int[] a = {1,23,21,32,12,3,2,4,12,21};
        int[] temp = new int[a.length];
        mergeSort(a,temp,0,a.length-1);
        for (int i:a) {
            System.out.print(i+"\t");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/sperospera/article/details/89222364