首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合并排序与插入排序

合并排序与插入排序
EN

Stack Overflow用户
提问于 2013-08-06 01:46:26
回答 1查看 3.4K关注 0票数 2

我在Java第4版中的算法中实现了一个合并排序。我的基本合并排序有效,当数组大小小于7时,我想使用插入排序来改进算法。我认为这是一个明显的有效改进,但实际上对于大数据来说,原来的改进比改进的要快。

下面是我改进的合并排序,剪切值= 7:

代码语言:javascript
复制
private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {

  // Copy to aux[]
  for (int i = lo; i <= hi; i++) {
    aux[i] = a[i];
  }

  // Merge back to a[]
  int i = lo, j = mid + 1;
  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[i], aux[j])) a[k] = aux[i++];
    else                           a[k] = aux[j++];
  }
}

private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {

  // #1 improvement
  // Stop condition for this recursion.
  // This time we add a CUTOFF, when the items in array
  // is less than 7, we will use insertion sort.
  if (hi <= lo + CUTOFF - 1) {
    Insertion.sort(a, lo, hi);
    return;
  }

  int mid = lo + (hi - lo) / 2;
  sort(a, aux, lo, mid);
  sort(a, aux, mid + 1, hi);
  if (!less(a[mid+1], a[mid])) return;
  merge(a, aux, lo, mid, hi);
}

public static void sort(Comparable[] a) {
  Comparable[] aux = new Comparable[a.length];
  sort(a, aux, 0, a.length - 1);
}

插入排序代码:

代码语言:javascript
复制
public static void sort(Comparable[] a, int lo, int hi) {
  for (int i = lo; i <= hi; i++) {
    for (int j = i; j > 0 && less(a[j], a[j - 1]); j--) {
      exch(a, j, j - 1);
    }
  }
}

我使用一个SortCompare.java来比较执行时间:

代码语言:javascript
复制
public class SortCompare {

  public static double time(String alg, Comparable[] a) {
    Stopwatch timer = new Stopwatch();
    if (alg.equals("Insertion")) Insertion.sort(a);
    if (alg.equals("Selection")) Selection.sort(a);
    if (alg.equals("Shell")) Shell.sort(a);
    if (alg.equals("Merge")) Merge.sort(a);
    if (alg.equals("MergeWithImprovements")) MergeWithImprovements.sort(a);
    //if (alg.equals("Quick")) Quick.sort(a);
    //if (alg.equals("Heap")) Heap.sort(a);
    if (alg.equals("InsertionWithSentinel")) InsertionWithSentinel.sort(a);
    return timer.elapsedTime();
  }

  public static double timeRandomInput(String alg, int N, int T) {
    // Use alg to sort T random arrays of length N.
    double total = 0.0;
    Double[] a = new Double[N];
    for (int t = 0; t < T; t++) {
      for (int i = 0; i < N; i++) {
        a[i] = StdRandom.uniform();
      }
      total += time(alg, a);
    }
    return total;
  }

  public static void main(String[] args) {
    String alg1 = args[0];
    String alg2 = args[1];
    int N = Integer.parseInt(args[2]);
    int T = Integer.parseInt(args[3]);
    double t1 = timeRandomInput(alg1, N, T);  // Total for alg1
    double t2 = timeRandomInput(alg2, N, T);
    StdOut.printf("For %d random Doubles\n   %s is", N, alg1);
    StdOut.printf(" %.1f times faster than %s\n", t2/t1, alg2);
  }
}

我生成了100个数组,每个数组有10000个元素。原始合并排序比改进的合并排序快30倍!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-06 02:20:12

插入排序函数肯定是错误的。注意j > 0结束条件。传入[lo..hi],但是代码可以迭代j直到1。我想你想要的是:

代码语言:javascript
复制
public static void sort(Comparable[] a, int lo, int hi) {
  for (int i = lo + 1; i <= hi; i++) {
    for (int j = i; j > lo && less(a[j], a[j - 1]); j--) {
      exch(a, j, j - 1);
    }
  }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18070546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档