代码之家  ›  专栏  ›  技术社区  ›  JimBelushi2

合并排序时出错

  •  1
  • JimBelushi2  · 技术社区  · 8 年前

    我制作了自己的合并排序,它有一个只允许使用ArrayList和Comparator的方法。我的同事要求我通常声明为“merge”方法的tmp数组必须声明为第一个包装器方法(mergeSort)。现在,如果我用3个元素执行一个测试,它将不起作用。为什么?

    public static < T > void mergeSort(ArrayList < T > array, Comparator < T > c) {
        int high = array.size()-1;
        sort(array, c, 0, high, new ArrayList < T > (high + 1));
      }  
    
      protected static < T > void sort(ArrayList < T > array, Comparator < T > c, int low, int high, ArrayList < T > tmp) {
        if (low < high) {
          int mid = low + (high - low) / 2;
          sort(array, c, low, mid, tmp);
          sort(array, c, mid + 1, high, tmp);
          merge(array, c, low, mid, high, tmp);
        }
      }
    
      protected static < T > void merge(ArrayList < T > array, Comparator < T > c, int p, int mid, int q, ArrayList < T > tmp) {
        int i = p;
        int j = mid + 1;
        int k = 0;
        for (; i <= mid && j <= q; k++) {
          if (c.compare(array.get(i), array.get(j)) < 0)
            tmp.add(k, array.get(i++));
          else
            tmp.add(k, array.get(j++));
        }
        if (i <= mid && j > q) {
          while (i <= mid)
            tmp.add(k++, array.get(i++));
        } else {
          while (j <= q)
            tmp.add(k++, array.get(j++));
        }
        for (k = 0; k < tmp.size(); k++)
          array.set(k + p, tmp.get(k));
      }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Eran    8 年前

    自从你 tmp ArrayList 以前是本地的 merge 方法,这意味着在将其移动到 mergeSort 调用时,应在每次调用中使用之前清除 合并 :

    protected static < T > void merge(ArrayList < T > array, Comparator < T > c, int p, int mid, int q, ArrayList < T > tmp) {
        tmp.clear();
        ...
    }
    

    在不清除它的情况下,您将在对的每次调用中不断向其添加元素 合并 。它将不断增长,您可能会重用其中过时的元素。