Как время сортировки массива может резко измениться в Java в зависимости от размера зазора?

Я в основном создаю 10 случайных массивов размером: 8000,16000,32000,64000,128000,256000

Я имею в виду, что у меня есть 10 массивов размером 8000, 10 массивов размером 16000 и т. д.

Все они заполнены случайными числами в диапазоне от 0 до размера массива.

У меня есть реализация для сортировки оболочки:

public static void sortMyArray(int[] a){
for (int gap = a.length / 2; gap > 0; gap = (gap / 2)) {
    for (int i = gap; i < a.length; i++) {
        int tmp = a[i];
        int j = i;
        for (; j >= gap && tmp < (a[j - gap]); j -= gap) {
            a[j] = a[j - gap];
        }
        a[j] = tmp;
     }
}
}

Когда зазор зазор = a.length / a. length у меня просто сортировка вставками. Вот время сортировки этих массивов:

Number of Elements  Milliseconds
8000                13
16000               53
32000               217
64000               828
128000              3311
256000              13352

Так что это примерно O (N ^ 2). Когда количество элементов удваивается, время решения увеличивается почти в 4 раза.

Однако, когда я использую gap = a.length/2, я получаю такие значения, как:

Number of Elements  Milliseconds
8000                2
16000               2
32000               4
64000               10
128000              25
256000              60

Так что это даже лучше, чем O(N), я думаю? Как это возможно? Я пробовал выключать процессоры из Windows и пробовал запускать компьютер только на 1 процессоре, однако значения все равно были нелогичными.

Вот мой полный код, если вам интересно:

int[] arraySizes = new int[]{8000,16000,32000,64000,128000,256000};
Random rn = new Random(1);

for(int i=0;i<arraySizes.length;i++){
    int[] arrayToBeSorted = new int[arraySizes[i]];
    System.out.println("Solving array with: " + arraySizes[i] + " elements with first sorting algorithm.");
    for (int c = 0; c < 10; c++) {
        for(int t=0;t<arraySizes[i];t++){
            int randomNumber = rn.nextInt(arrayToBeSorted.length);
            arrayToBeSorted[t] = randomNumber;
        }
        Long initialTime = (new Date().getTime());
        sortMyArray(arrayToBeSorted);
        Long finalTime = (new Date().getTime());
        System.out.println("Time in milliseconds:" + (finalTime - initialTime));
    }
}

person Koray Tugay    schedule 15.05.2013    source источник
comment
Случайный rn = новый случайный (1); это кажется подозрительным. просто используйте Random по умолчанию rn = new Random(); или поместите большое случайное семя, например Random rn = new Random(730495);   -  person tgkprog    schedule 16.05.2013
comment
Как действует семя, почему вызывает подозрения?   -  person Koray Tugay    schedule 16.05.2013
comment
я недостаточно знаю о генераторах случайных чисел, но важно то, что я прочитал. Я сделал пример приложения, но для меня время не меняется -> Решение массива с: 256000 элементов с первым алгоритмом сортировки. Время в миллисекундах: 213 (всегда получайте от 207 до 223) для промежутка = a.length и промежутка = a.length / 2   -  person tgkprog    schedule 16.05.2013
comment
Обратите внимание, что использование фиксированного начального числа приводит к смещению результата в сторону последовательности чисел, сгенерированных начальным числом.   -  person nhahtdh    schedule 16.05.2013


Ответы (1)


Хотя ваши реализации кажутся правильными, ваше предположение — нет.

Вы предполагаете, что если функция имеет сложность O (n ^ 2) и время выполнения 3311 секунд, то какая-то другая функция со сложностью O (n) должна работать около 57 секунд на тех же данных.

Однако нотация большого O дает представление о скорости роста функции, а не о фактическом времени выполнения. Поэтому вы не можете просто сравнивать время работы различных функций в зависимости от скорости их роста.

person bsrykt    schedule 16.05.2013
comment
Здравствуйте, я хочу сказать, что при сортировке вставками, когда размер массива увеличивается на кратное 2, время выполнения увеличивается на 4 степени. Таким образом, время выполнения зависит от квадрата числа элементов в массиве. Однако, когда размер промежутка равен 2, когда количество элементов в массиве удваивается, соответственно удваивается и время выполнения. - person Koray Tugay; 16.05.2013
comment
Что вы имеете в виду, когда размер зазора равен 2? - person bsrykt; 16.05.2013
comment
Извините, я имею в виду a.length/2. Размер зазора равен половине массива. В ситуации сортировки сдвигом. - person Koray Tugay; 16.05.2013
comment
Это неверно: когда количество элементов в массиве удваивается, соответственно удваивается и время выполнения. 60/25 = 2,4, 25/10 = 2,5 и т. д. - person bsrykt; 16.05.2013