归并排序

138 阅读2分钟

归并排序

整体思想

分治(divide-and-conquer)

具体步骤

  1. sort 排序 拆分待排序数组,当拆分成数组元素只有一个的时候 即 {1} 或者{47} 默认为已排序
  2. merge 合并 将排好序的数组按照大小存储在temp临时数组中,扫描左右两数组并将数字从小到大放入temp数组中, 但是扫描过程可能扫描完左数组就退出,或者扫描完右数组就退出,所以我们需要将剩余元素直接填充到temp数组中。 例如 {38,49} {65,97} 进行合并过程中,38,49依次进入temp数组,而右数组的数字仍未操作过,所以需要进一步判断。

具体代码 Sort

public static int[] sort(int[] a,int low,int high){
//每次将数组拆分一半, 直到low==high
        int mid = (low+high)/2;
        if (low<high){
        //左边数组排序
            sort(a,low,mid);
            //右边数组排序
            sort(a,mid+1,high);
            //合并
            merge(a,low,mid,high);
        }
        return a;
    }

具体代码 Merge

public static void merge(int[] a, int low, int mid, int high) {
        //临时数组存储排序元素
        int[] temp = new int[high-low+1];
        int i = low;
        int j = mid+1;
        int k = 0;

        while(i<=mid && j<=high){
            if (a[i]<a[j]){
                temp[k++] = a[i++];
            }else{
                temp[k++] = a[j++];
            }
        }
        while (i<=mid){
            temp[k++] = a[i++];
        }
        while(j<=high){
            temp[k++] = a[j++];
        }
        //从low当前位置开始 
        //将temp数组中k个已排好序元素放入target目标数组a中
        for (int x= 0;x<k;x++){
            a[low+x] = temp[x];
        }
    }

案例:

int[] a = {44,2,77,34,12,87,14,1};

排序结果

[1, 2, 12, 14, 34, 44, 77, 87]

可改进部分

在排序sort方法中提前声明temp临时数组变量,防止递归调用中重复创建对象,造成资源浪费以及占用。