Я хочу узнать различия между двумя функциями, организованными с помощью быстрой сортировки - PullRequest
0 голосов
/ 06 мая 2020

Вопрос

Следующие randomQuickSort1(target, left, right) и randomQuickSort2(target, left, right) были созданы на основе общей c случайной быстрой сортировки. Я ищу пример массива, который занимает несколько секунд, когда я использую randomQuickSort1(target, left, right), в то время как это занимает много времени, когда я использую randomQuickSort2(target, left, right). Я знаю разницу в объеме пространственных вычислений между двумя функциями, но не знаю, как / что влияет на количество вычисленного времени.

Подготовленная быстрая сортировка

partition(target, left, right) делит числа больше pivot слева и меньшие, чем pivot справа. randomQuickSort1(target, left, right) сортирует от самого короткого левого или правого сегмента, а randomQuickSort2(target, left, right) сортирует с левой стороны сегмента.

int partition_not_random(int* target, int left, int right) {
    // ****************** CHANGE ******************
    int random = right - 1;
    // ****************** CHANGE ******************    
    // Exchange target[right] and target[random].
    int tmp = target[right]; target[right] = target[random]; target[random] = tmp;
    int pivot = target[right];
    int i = left-1; // i scans the array from the left.
    int j = right;  // j scans the array from the right.
    for (;;) {
        // Move from the left until hitting a value no less than the pivot.
        for(i++; target[i] < pivot; i++){}
        // Move from the right until hitting a value no greater than the pivot.
        for(j--; pivot < target[j] && i < j; j--){}
        if (i >= j)  break;
        // Exchange target[i] and target[j].
        tmp = target[i];  target[i] = target[j];  target[j] = tmp;
    }
    // Exchange target[i] and target[right].
    tmp = target[i];  target[i] = target[right];  target[right] = tmp;
    return i;
}

void randomQuickSort1(int* target, int aLeft, int aRight) {
    int left = aLeft; int right = aRight;
    while (left < right) {
        int i = partition_not_random(target, left, right);
        if( i - left <= right - i ){ // The left interval is shorter.
            randomQuickSort1(target, left, i-1);
            left=i+1;
        }else{                       // The right interval is shorter.
            randomQuickSort1(target, i+1, right);
            right=i-1;
        }
    }
}
void randomQuickSort2(int* target, int aLeft, int right) {
    int left = aLeft;
    while (left < right) {
        int i = partition(target, left, right);
        randomQuickSort2(target, left, i-1);
        left = i+1;
    }
}

Обычная быстрая случайная сортировка

int partition(int* target, int left, int right) {
    // Select a number between left and right at random.
    int random = left + rand() % (right - left + 1);
    // Exchange target[right] and target[random].
    int tmp = target[right]; target[right] = target[random]; target[random] = tmp;
    int pivot = target[right];
    int i = left-1; // i scans the array from the left.
    int j = right;  // j scans the array from the right.
    for (;;) {
        // Move from the left until hitting a value no less than the pivot.
        for(i++; target[i] < pivot; i++){}
        // Move from the right until hitting a value no greater than the pivot.
        for(j--; pivot < target[j] && i < j; j--){}
        if (i >= j)  break;
        // Exchange target[i] and target[j].
        tmp = target[i];  target[i] = target[j];  target[j] = tmp;
    }
    // Exchange target[i] and target[right].
    tmp = target[i];  target[i] = target[right];  target[right] = tmp;
    return i;
}

void randomQuickSort(int* target, int left, int right ) {
    if (left < right) {
        int i = partition(target, left, right); // i: Position of the pivot.
        randomQuickSort1(target, left, i - 1);
        randomQuickSort1(target, i + 1, right);
    }
}

Что Я пробовал

Я пробовал массивы с сортировкой по возрастанию и массивы с сортировкой по убыванию, но не было никакой разницы во времени выполнения между двумя функциями.

...