归并排序

归并排序的同样是采用分治思想实现的一种优秀排序算法,它的主要思路是将一个大问题分成若干小问题,然后将小问题得出的结果依次合并,得出最后大问题的解。

该算法需要一个长度为n的辅助空间,所以空间复杂度为O(n),时间复杂度为O(nlogn),是一种稳定的排序算法。对了,排序算法是否稳定,取决于相同的key值在排序前后的位置是否发生改变。

归并排序的实现较为复杂,需要两个辅助函数。首先是一个将两个有序序列归并为一个有序序列的函数。

    //  将两个有序序列归并为一个有序序列
//  r为有两段有序序列的数组,order为新有序序列数组
//h为第一个有序序列的起始下标,m为终止下标,t为第二个有序序列的终止下标
    public static void merge(int [] r,int [] order,int h,int m,int t){
        int k = h; 
        int i = h;
        int j = m+1;
//      依次比较前后两序列的大小,小的放入order数组中
        while(i<=m&&j<=t)
        {
            if (r[i]<r[j]) {
                order[k] = r[i];
                k++;
                i++;
            }
            else {
                order[k] = r[j];
                k++;
                j++;
            }
        }
//      将剩下的元素复制到order数组中
        while (i<=m) {
            order[k] = r[i];
            k++;
            i++;
        }
        while (j<=t) {
            order[k] = r[j];
            k++;
            j++;
        }
    }
//  测试算法实现
//  public static void main(String args[]){
//      int [] a = {52,39,56};
//      int [] b = new int [a.length];
//      merge(a,b,0,0,2);
//      for (int j = 0; j < b.length; j++) {
//          System.out.print(b[j]);
//      }
//  }

一趟归并排序算法

    //  一次归并排序
//  s为有序序列的长度,每归并一次加倍
    public static void merges(int [] r,int[] order, int s){
        int p = 0;
        while(p+2*s-1<=r.length-1){
            merge(r, order, p, p+s-1,p+2*s-1);
            p = p+2*s;
        }
//      归并最后两个长度不等的有序表
        if (p+s-1<r.length-1) {
            merge(r, order, p, p+s-1, r.length-1);
        }
//      将剩余的数据复制到order中
        else {
            for (int i = p; i <= r.length-1; i++) {
                order[i] = r[i];
            }
        }
    }
//  测试算法
//  public static void main(String [] args){
//      int [] a = {52,39,67,95,70,8,25,52,56};
//      int [] b = new int [a.length];
//      merges(a,b,1);
//      for (int i = 0; i < b.length; i++) {
//          System.out.print(b[i]+" ");
//      }
//  }

实现归并算法

    //  实现归并排序
    public static int [] mergesort(int [] r){
        int s = 1;
        int [] order = new int [r.length];
        while (s<r.length) {
//          一次归并后,order由子有序序列组成,r为非有序序列
            merges(r, order, s);
            s = 2*s;
//          以order为目标序列,再归并到r
            merges(order, r, s);
            s = 2*s;
        }

        return r;
    }
//  测试
    public static void main(String [] args){
        int [] a = {52,39,67,95,70,8,25,52,56};
        int [] b = mergesort(a);
        for (int i = 0; i < b.length; i++) {
            System.out.print(b[i]+" ");
        }
    }
点赞