C ++ быстрая сортировка времени выполнения - PullRequest
1 голос
/ 29 апреля 2010

У меня вопрос по алгоритму быстрой сортировки. Я реализую алгоритм быстрой сортировки и играю в него. Элементы в исходном несортированном массиве являются случайными числами, выбранными из определенного диапазона. Я нахожу диапазон случайных чисел, влияющих на время работы. Например, время работы 1000 000 случайных чисел, выбранных из диапазона (1 - 2000), занимает 40 секунд. В то время как из диапазона 1 000 000 выбирается число 1 000 000 (1 - 10 000). Но я не знаю, как это объяснить. В классе мы говорим о том, что значение pivot может влиять на глубину дерева рекурсии. Для моей реализации последнее значение массива выбрано в качестве основного значения. Я не использую рандомизированную схему для выбора значения разворота.

int partition( vector<int> &vec, int p, int r) {

  int x = vec[r];
  int i = (p-1);
  int j = p;
  while(1) {

    if (vec[j] <= x){
      i = (i+1);
      int temp = vec[j];
      vec[j] = vec[i];
      vec[i] = temp;
    }
    j=j+1;
    if (j==r)
      break;
 }
  int temp = vec[i+1];
  vec[i+1] = vec[r];
  vec[r] = temp;
  return i+1;
}

void quicksort ( vector<int> &vec, int p, int r) {

  if (p<r){
    int q = partition(vec, p, r);
    quicksort(vec, p, q-1);
    quicksort(vec, q+1, r);
  }
}

    void random_generator(int num, int * array) {

      srand((unsigned)time(0)); 
      int random_integer; 
      for(int index=0; index< num; index++){ 
        random_integer = (rand()%10000)+1; 
        *(array+index) = random_integer; 
      } 
    }

    int main() {
      int array_size = 1000000;
      int input_array[array_size];
      random_generator(array_size, input_array);
      vector<int> vec(input_array, input_array+array_size);

      clock_t t1, t2;
      t1 = clock();
      quicksort(vec, 0, (array_size - 1));   // call quick sort
      int length = vec.size();
      t2 = clock();
      float diff = ((float)t2 - (float)t1);
      cout << diff << endl;
      cout << diff/CLOCKS_PER_SEC <<endl;
    }

Ответы [ 3 ]

5 голосов
/ 29 апреля 2010

Скорее всего, он неэффективен, потому что быстрая сортировка не очень хорошо обрабатывает множество дубликатов и может привести к их замене (порядок элементов с равным ключом не гарантируется). Вы заметите, что число дубликатов на число равно 100 для 10000 или 500 для 2000, в то время как фактор времени также приблизительно равен 5.

Усредняли ли вы время выполнения по крайней мере 5-10 прогонов для каждого размера, чтобы получить хороший шанс получить хороший стартовый круг?

Для сравнения вы проверили, как std :: sort и std :: stable_sort также работают с теми же наборами данных?

Наконец, для этого распределения данных (если это не упражнение по быстрой сортировке) я думаю, что сортировка по подсчетам была бы намного лучше - память 40 КБ для хранения счетчиков, и она работает в O (n).

0 голосов
/ 24 мая 2019

Поздний ответ - влияние дубликатов зависит от схемы разбиения. Пример кода в вопросе - это вариант схемы разбиения Lomuto, который занимает больше времени по мере увеличения числа дубликатов из-за ухудшения разбиения. В случае всех равных элементов Lomuto уменьшает размер только на 1 элемент с каждым уровнем рекурсии.

Если вместо этого использовалась схема разбиения Hoare (со средним значением в качестве точки разворота), это обычно занимает меньше времени по мере увеличения числа дубликатов. Hoare излишне поменяет значения, равные центральной точке, из-за дубликатов, но разбиение подойдет к идеальному случаю разделения массива на части почти одинакового размера. Затраты на перестановку несколько маскируются кешем памяти. Ссылка на пример Wiki схемы разделов Hoare:

https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme

0 голосов
/ 29 апреля 2010

Вероятно, это связано с тем, насколько хорошо отсортирован ввод. Быстрая сортировка - это O (n logn), если ввод является случайным. Если это в обратном порядке, производительность может снизиться до O (n ^ 2). Возможно, вы приближаетесь к поведению O (n ^ 2) с меньшим диапазоном данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...