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

array.sort(object[]a)-它是如何实现的?

  •  6
  • helpermethod  · 技术社区  · 16 年前

    是否有关于如何实现数组使用的mergesort.sort(object[]a)的资源?虽然文档记录得很好,但我很难理解它(尤其是当mergesort()get递归调用时,为什么会切换src和dest)。

    2 回复  |  直到 15 年前
        1
  •  11
  •   Bozho    16 年前

    Here is the source 属于 java.util.Arrays .

    事实上,JDK中有这个源代码-刚刚打开 java.util.数组 在您的IDE和源代码+中,注释将出现。如果你没有IDE,看看 JDK_HOME\src.zip

    然后,将它放在您的IDE中并跟踪它的工作原理。

    • 放置断点(并在调试模式下运行程序)
    • 使用 System.out.println(..)
    • 改变它的一部分,看看它们是如何反映出来的。
    • 阅读 wikipedia article about merge sort
    • 请注意以下评论: // Recursively sort halves of dest into src
        2
  •  0
  •   lostinmoney    15 年前

    我和你有过同样的困惑。据我所知,这种转换的原因很简单——使得后续的合并步骤更容易。没有魔法。

        private static void mergeSortWithoutSwitch(Object[] src, Object[] dest, int low, int high, int off) {
        int length = high - low;
    
        // Insertion sort on smallest arrays
        if (length < INSERTIONSORT_THRESHOLD) {
            for (int i = low; i < high; i++)
                for (int j = i; j > low && ((Comparable) dest[j - 1]).compareTo(dest[j]) > 0; j--)
                    swap(dest, j, j - 1);
            return;
        }
    
        // Recursively sort halves of dest into src
        int destLow = low;
        int destHigh = high;
        low += off;
        high += off;
        int mid = (low + high) >>> 1;
        mergeSortWithoutSwitch(src, dest, low, mid, off);
        mergeSortWithoutSwitch(src, dest, mid, high, off);
    
        // If list is already sorted, just copy from src to dest. This is an
        // optimization that results in faster sorts for nearly ordered lists.
        if (((Comparable) dest[mid - 1]).compareTo(dest[mid]) <= 0) {
            return;
        }
    
        // Merge sorted halves (now in src) into dest
        for (int i = destLow, p = low, q = mid; i < destHigh; i++) {
            if (q >= high || p < mid && ((Comparable) dest[p]).compareTo(dest[q]) <= 0)
                src[i] = dest[p++];
            else
                src[i] = dest[q++];
        }
    
        // copy back
        for (int i = destLow; i < destHigh; i++) {
            dest[i] = src[i];
        }
    
    }
    

    上面是没有切换的实现,从代码中,您可以看到我们在合并中还需要一个步骤——复制回来。我觉得mergesort中的参数命名有点混乱,因为src是只在合并步骤中使用的辅助数组,所以最好用aux来命名它(我们甚至可以从方法签名中删除它,并在合并时创建一个局部变量)。dest是结果数组。