归并排序

java excel merge 居中 java merge sort_合并


思想:先将数组中的每两个进行合并并且在合并的过程中进行排序,然后每四个进行合并。一直到数组合并完成。
例如上图中:要对数组中的元素:80、30、60、20、10、60、50、70进行排序,先把数组分成8组先分别对这八组进行合并排序,(30,80),(20,60),(10,60),(50,70)这四组组内已经排好序。然后继续排序(20,30,60,80)(10,50,60,70)最后对这两组排序(10,20,30,50,60,60,70,80)


package Sort;

import java.util.Arrays;

public class MergeSort {

    public static void main(String[] args) {
        int []array={80,30,60,20,10,60,50,70};
        int []copy=new int[array.length];
        //为数组分配一个数组空间来进行排序,排完序后还要复制给原数组
        for(int i=0;i<array.length;i++)
        {
            copy[i]=array[i];
        }
        mergeSort(array,copy,0,array.length-1);
        System.out.println(Arrays.toString(array));
    }
    public static void mergeSort(int []array,int []copy,int start,int end)
    {
        if(start==end)
        {
            return;
            //如果数组长度为0则直接返回
        }
        int length=(end-start)/2;
        //将数组分为左右两部分,分别对左右两部分进行排序
        mergeSort(array, copy, start, start+length);
        mergeSort(array, copy, start+length+1, end);
        int copyindex=end;
        int i=start+length;
        int j=end;
        //将左右两个排好序的数组进行排序,将结果保存到copy数组中
        while(i>=start&&j>=start+length+1)
        {
        //将左右数组由大到小复制到copy数组中
            if(array[i]>array[j])
            {
                copy[copyindex--]=array[i--];

            }
            else {
                copy[copyindex--]=array[j--];
            }
        }
        while(i>=start)
        {
            copy[copyindex--]=array[i--];
            //因为左数组中剩下的肯定比copy数组中最小的还小,如果左边的数组还有,则将其复制到copy数组中,
        }
        while (j>=start+length+1) {
            copy[copyindex--]=array[j--];   
                //因为右数组中剩下的肯定比copy数组中最小的还小如果右边的数组还有,则将其复制到copy数组中       
        }
        for(i=start;i<=end;i++)
        {
            array[i]=copy[i];
            //将copy数组复制到array数组中。
        }
    }
}

改进版归并排序

public static void mergeSort1(int []array,int []copy,int low,int high)
    {
        int len=high-low+1;
        if(len<7)
        {
            for(int i=low;i<=high;i++)
            {
                for(int j=i;j>low&&array[j]<array[j-1];j--)
                {
                    swap(array, j, j-1);
                }
            }
            return;     
        }
        int mid=(low+high)>>>1;
        mergeSort1(copy, array, low, mid);
        //交换了copy 和array数组,这样便省去了将array数组复制给copy数组。
        mergeSort1(copy, array, mid+1, high);
        //如果左数组的最大值小于右数组的最小值,则数组已经排好序,直接进行复制。
        if(copy[mid]<copy[mid+1])
        {
            System.arraycopy(copy, low, array, low, len);
            return ;
        }
        int left=low,right=mid+1;
        for(int i=low;i<=high;i++)
        {
            if(right>high||left <=mid &©[left]<copy[right])
                array[i]=copy[left++];
            else {
                array[i]=copy[right++];
            }
        }
    }
    private static void swap(int[] x, int a, int b) {
        int t = x[a];
        x[a] = x[b];
        x[b] = t;
    }

上面归并排序做了一下改进来优化性能。
①当数组的长度小于7时对数组进行插入排序,这样速度更快,并且更节约空间。

②如果一次对左右进行排序后发现左边数组的最大值小于右边数组的最小值,则数组是已经排好序的直接复制给目标数组。

③在排序过程中交换辅助数组和目标数组,这样可以减少复制目标数组到辅助数组的过程。

上一篇:堆排序HeapSort

下一篇:快速排序 QuickSort