#algorithm #sorting #big-o #quicksort #mergesort
#алгоритм #сортировка #big-o #быстрая сортировка #сортировка слиянием
Вопрос:
Я начинающий программист, и я придумал алгоритм сортировки (DexSort), который обычно работает намного быстрее, чем стандартная быстрая сортировка. Предполагается, что количество ВСЕХ ВОЗМОЖНЫХ значений в наборе / массиве меньше N ^ 2, где N — количество элементов, которые я пытаюсь отсортировать. Я пытаюсь найти способ оптимизировать его, чтобы он не обязательно зависел от ВСЕХ ВОЗМОЖНЫХ ЗНАЧЕНИЙ и только от подмножества значений, которые имеют отношение.
Например …. скажем, у меня есть массив случайных чисел, где array.length = 10 миллионов. Мой алгоритм работает только быстрее, чем быстрая сортировка (в среднем), когда общее количество всех возможных значений меньше N ^ 2 (т. е. 10^7 * 10^7 = 10 ^ 14). Теперь, скажем, есть 10 ^ 14 фактических значений, которые можно найти в массиве. В этот момент мой алгоритм будет выполняться примерно со скоростью O (10 ^ 14). Может кто-нибудь придумать способ, где я мог бы уменьшить это?
Вот мой код на Java:
package sort;
import java.util.*;
public class DexSort {
public static Comparable[] dexSort(Comparable[] c, int max){
//The variable int max is the maximum number of possible values
//E.g. If you are trying to sort 7-digit phone numbers, max = Math.pow(10,8) - 1, or 10^8 - 1
int size = c.length;
Comparable[] sorted = new Comparable[size];
int[] array = new int[max 1];
for (int i = 0; i < size; i ){
int val = (int) c[i];
int count = array[val];
count ;
array[val] = count;
}
int next = 0;
while (next < size){
for (int i = 0; i <= max; i ){
int count = array[i];
if (count > 0){
for (int j = 0; j < count; j ){
sorted[next] = i;
next ;
}
}
}
}
return sorted;
}
public static void main(String[] args){
Random r = new Random(7);
for (double n = 4; n < 8; n ){
double size = Math.pow(10, n);
System.out.println("---------------------------------------------");
System.out.println("Filling array size: 10^" n);
System.out.println("---------------------------------------------n");
Comparable[] array = fillArray((int)size, r); //Create array of random numbers of specified size
System.out.println("Array filled"); //Tests different array sizes by incrementing a power of 10
System.out.println("---------------------------------------------n");
double max = size; //Arbitrarily set the maximum value possible as the array size
//Runtime will depend heavily on max if max>>>> size (See dexSort method)
//Overall, runtime will be O(max) when max >>>>> size
double t0 = System.nanoTime();
array = dexSort(array, (int) max);
double tF = System.nanoTime();
double nanoSecs = tF - t0;
double secs = nanoSecs/Math.pow(10, 9);
System.out.println("DEX sort complete");
System.out.println("It took " String.format("%.3f", secs) " seconds to sort an array of size 10^" n);
//printArray(array); //Uncomment this line to print sorted array to console
System.out.println();
System.out.println("---------------------------------------------");
System.out.println("---------------------------------------------nn");
}
}
public static Comparable[] fillArray(int size, Random r){
Comparable[] c = new Comparable[size];
for (int i = 0; i < size; i ){
/*if ((i 1)000000 == 0){
System.out.println(((i 1)/1000000) " million filled");
}*/
c[i] = r.nextInt(size) 1;
}
return c;
}
public static void printArray(Comparable[] c){
for (int i = 0; i < c.length; i ){
if (i == 0){
System.out.println();
}
System.out.print(c[i] "t");
}
}
}
Комментарии:
1. en.wikipedia.org/wiki/Pigeonhole_sort
2. Пример кода выглядит как сортировка с подсчетом, где array[] содержит подсчеты. Если максимальное значение равно n ^ 2, возможно, вам захочется рассмотреть возможность использования варианта сортировки по принципу lsd (наименьшая значащая цифра). Популярным выбором является сортировка по основанию 256 (8-битные подполя).
3. Я считаю, что вы правы, спасибо!
4. «Например …. скажем, у меня есть массив случайных чисел, где array.length = 10 миллионов. … мой алгоритм будет выполняться примерно с O (10 ^ 14).» Как он может работать быстрее, чем быстрая сортировка? При N = 10 ^ 7 (10 миллионов) сложность быстрой сортировки во время выполнения примерно равна O (10 ^ 7 log(10 ^ 7)) ~ O ((10 ^ 7) * 7 * log(10) ~ O(23.25 * (10^7)). Сложность во время выполнения 0 (10 ^ 14) для массива из 10 ^ 7 элементов звучит как пузырьковая сортировка или сортировка по вставке, а не быстрее, чем быстрая сортировка.
5. Алгоритм будет выполняться примерно с 10 ^ 14, если диапазон всех возможных значений равен 10 ^ 14. Если я смотрю только на набор значений 10 ^ 7, то он будет выполняться с O (2n) Быстрая сортировка не будет зависеть от диапазона всех возможных значений, в которые я не верю, поскольку он просто использует точки поворота в образце.