当前位置: 首页 > 知识库问答 >
问题:

我正在对长度为10000到75000的整数数组进行合并排序。我的时间越来越奇怪了。为什么会这样?

卫俊力
2023-03-14

我正在为我的算法类做一个赋值,我必须证明内部合并排序的时间复杂度为O(n logn)。为此,我制作了长度从10000个元素到75000个元素的数组。然后,我将随机数加载到10000以下的数组中,并将数组长度与排序所需的时间一起输出到控制台。

奇怪的结果是,有些数组需要约15毫秒的给定或获取,而另一些数组则需要0毫秒,即使数组的长度要长数万个整数。你知道为什么吗?我可以上传输出的屏幕截图,但需要有人批准,因为我没有足够的“声誉”。我已经检查了阵列。调用mergeSort()方法后,它们看起来确实被排序了。

public static void main(String[] args){
    int[] dataLength = { 10_000, 15_000, 20_000, 25_000, 30_000,
                         35_000, 40_000, 45_000, 50_000, 55_000,
                         60_000, 65_000, 70_000, 75_000 };
    // internal merge sort
    for (int i = 0; i < dataLength.length; i++) {
        int[] input = new int[dataLength[i]];
        for (int j = 0; j < input.length; j++) {
            input[j] = random.nextInt(10000);
        }

        long startTime = System.currentTimeMillis();
        mergeSort(input, 0, input.length);
        long endTime = System.currentTimeMillis();

        System.out.println("Length of array is: " + input.length + ". The sorted array: " +
                           Arrays.toString(input));
        System.out.println("Internal sort with " + dataLength[i] + " items took: " +
                           (endTime - startTime) + " milliseconds");
    }
}

public static void mergeSort(int[] input, int start, int end) {
    if (end - start < 2) {
        return;
    }

    int mid = (start + end) / 2;
    mergeSort(input, start, mid);
    mergeSort(input, mid, end);
    merge(input, start, mid, end);
    return;
}

public static void merge(int[] input, int start, int mid, int end) {
    if (input[mid - 1] <= input[mid]) {
        return;
    }
 //        index of "left" array
    int i = start;
 //        index of "right" array
    int j = mid;
    int tempIndex = 0;
    int[] temp = new int[end - start];

    while (i < mid && j < end) {
        temp[tempIndex++] = input[i] <= input[j] ? input[i++] : input[j++];
    }
 //        optimizes the merge. If there are elements in the left array we just copy them back
 //        into the input array instead of merging them with the temp array first
    System.arraycopy(input, i, input, start + tempIndex, mid - i);
    System.arraycopy(temp, 0, input, start, tempIndex);
    return;
}

共有1个答案

白浩荡
2023-03-14

评论中的几个考虑因素:

  • 在Windows中,ystem.currentTimeMillis()为您提供64 hz(或15.625 ms)精度的时钟,因此最小差异为15 ms。
  • 给定您对数组的随机初始化,它们将被部分排序,并且对部分排序的数组进行排序将比未排序的数组(略)快

当你把可复制性问题加在一起时,很明显,要得到显示O(n logn)复杂性的合理结果,你应该:

  • 使用System.nano时间获得更精确的时钟测量。
  • 使用较大的数组来扩大时间差
  • 使用像JMH这样的代码分析器/基准测试
 类似资料:
  • 我一直在研究一种合并排序算法,我想最终用它对字符串数组进行排序。 理论上,我对一个包含ID的数组进行排序,我想按照与字符串主数组相同的顺序对其进行排序,然后对ID数组进行排序,并对字符串数组执行相同的操作,理论上对它们进行相同的排序。 例如,ID值的数组可以是[1,2,3,4,5],而主数组看起来像["Name,1","Name,2"]... 当我在不包含任何第二个数组部分的情况下运行算法时,它工

  • 我正在学习Python和一些基本的数据结构和算法。我实现了自己版本的合并排序,但我不明白为什么它会改变输入数组的顺序。它的行为就像我在mergesort()函数中将输入数组作为全局引用一样,但我没有这样做。从我实现代码的方式来看,我认为应该在函数的本地范围内对输入数组的副本进行排序,然后返回该副本的排序版本,保持输入数组不变。然而,事实并非如此。它正确地对数组排序;我只是被一个似乎是范围问题的问题

  • 问题内容: Python 3.X的功能不能被依赖于排序异质序列,因为大多数对不同类型的是unorderable(数字类型喜欢,,等是一个例外): 相反,没有自然顺序的对象之间的比较是任意的,但在Python 2.x中是一致的,因此可以: 为了复制在Python 3.X的Python 2.x的行为,我写了一个类来用作key参数sorted(),这依赖于这样一个事实是保证只使用低于比较: 用法示例:

  • 第1034行:Char 9:运行时错误:引用绑定到'std::vector'类型的空指针

  • 我正在设置合并排序来对数组进行排序。目标是对任意长度的数组进行排序。 我试过查看mergesort函数,但没有发现任何问题。排序适用于某些数组长度,无论是奇数还是偶数,但对于数组长度,例如长度为10,我得到了一个上界异常。

  • 我写了一个输出斐波那契数列的程序,这个程序对很小的数字工作得很好。当我将循环设置为序列的第10000个数字时,程序变得非常奇怪,开始输出负数和正数。 起初我认为这是因为我对数字使用了int类型,但后来我将其改为long,程序仍然输出相同的内容。我对java很陌生,所以我想要么是我的程序出了问题,要么是我错过了一个大于long并且不会输出负数的类型。 第91次:-624658365858767487