面试题51——归并排序的一个优化(想的时间有点久)

时间:2021-07-12
本文章向大家介绍面试题51——归并排序的一个优化(想的时间有点久),主要包括面试题51——归并排序的一个优化(想的时间有点久)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

排序算法之——归并排序(两种方法及其优化)(关于算法的实现具体看链接)

本文将围绕代码从多个方面分析归并算法,归并的操作很简单,稍加思考便能深刻理解。重点理解第三个优化的实现,其实就是在merge里少了一步复制,如果只是传入一个原数组,需要将原数组复制到辅助数组。然后再通过辅助数组归并排序。

而如果传入了两个数组,其中的一个数组的子数组已经排好序了,就可以直接归并了,不需要复制。

这需要通过技巧,如果sort函数的形参是(A,AUX),则每次递归时sort函数实参应该传入(AUX,A)(sort函数中的merge函数的实参为(A,AUX))

优化后的merge函数,注意第一个for循环已经被注释掉了

public static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {// 原地归并的抽象方法
        int i = lo, j = mid + 1;
         // for (int k = lo; k <= hi; k++) {
         // aux[k] = a[k];
         // }
        for (int k = lo; k <= hi; k++) {
            if (i > mid) {
                 a[k] = aux[j++];
             } else if (j > hi) {
                 a[k] = aux[i++];
             } else if (less(aux[j], aux[i])) {
                 a[k] = aux[j++];
             } else {
                 a[k] = aux[i++];
             }
         }
     }
优化后的sort函数,注意里面还有书上提到的其余两个优化,注意实参形参的使用。
private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
         /*
          * 自顶向下的并归排序 三个改进
          */
         // if (hi <= lo) {
         // return;
         // }
        int mid = lo + (hi - lo) / 2;
        if (hi - lo <= 7) {// 对小规模子数组使用插入排序
             //System.out.println("insert!");
             insertionSort(a, lo, hi);
             return;
         }
         sort(aux, a, lo, mid);
         sort(aux, a, mid + 1, hi);
         if (!less(aux[mid + 1], aux[mid])) {// 已经有序时跳过merge(a中lo到mid mid到hi分别都是有序的)
             System.arraycopy(aux, lo, a, lo, hi-lo+1);
             return;
         }
         merge(a, aux, lo, mid, hi);
     }

原文地址:https://www.cnblogs.com/lijinshu/p/15004237.html