【问题标题】:Why does Radix sort has larger number of instructions than Quick sort in C?为什么基数排序比 C 中的快速排序有更多的指令?
【发布时间】:2015-04-05 22:12:29
【问题描述】:

我在 C 中设置了 2 个排序算法函数,基数排序和快速排序
但是当我用 gdb 检查这些功能时,发现快速排序的指令数量比基数排序少。而且感觉更快...
据我所知,基数排序是最快的排序算法。
以下是我在 wiki 上的排序代码。
1.快速排序

void q_sort(int numbers[], int left, int right)
 {
   if(left == right) return;
   int pivot, l_hold, r_hold;
   l_hold = left;
   r_hold = right;
   pivot = numbers[left];

   while (left < right)
   {
     while ((numbers[right] >= pivot) && (left < right))
       right--;

     if (left != right)
     {
       numbers[left] = numbers[right];
       left++;
     }

     while ((numbers[left] <= pivot) && (left < right))
       left++;

     if (left != right)
     {
       numbers[right] = numbers[left];
       right--;
     }
   }

   numbers[left] = pivot;
   pivot = left;
   left = l_hold;
   right = r_hold;

   if (left < pivot)
     q_sort(numbers, left, pivot-1);
   if (right > pivot)
     q_sort(numbers, pivot+1, right);
 }

2.基数排序

/**
 * @data  array
 * @size  the number of array
 * @p  cipher of the biggest number
 * @k  notation( in case of decimal, it is 10)

 */
void rxSort(int *data, int size, int p, int k) {
     int *counts,
     *temp;
     int index, pval, i, j, n;
     if ( (counts = (int*) malloc(k * sizeof(int))) == NULL )
          return;
     if ( (temp = (int*) malloc(size * sizeof(int))) == NULL )
          return;
     for (n=0; n<p; n++) {
          for (i=0; i<k; i++)
               counts[i] = 0; // initialize

          // n:0 => 1,  1 => 10, 2 => 100
          pval = (int)pow((double)k, (double)n);
          for (j=0; j<size; j++) {
               // if the number is  253
               // n:0 => 3,  1 => 5, 2 => 2
               index = (int)(data[j] / pval) % k;
               counts[index] = counts[index] + 1;
          }
          for (i=1; i<k; i++) {
               counts[i] = counts[i] + counts[i-1];
          }
          for (j=size-1; j>=0; j--) {
               index = (int)(data[j] / pval) % k;
               temp[counts[index] -1] = data[j];
               counts[index] = counts[index] - 1;
          }

          memcpy(data, temp, size * sizeof(int));
     }
}

有一些限制如下
1.数组大小设置为256.
2.数字范围为0~64。
3. 对不同的数组进行四次运算。

当我测试时,我将数组的大小设置为 50
然后,指令的数量
基数:15030
快速 : 7484
快速获胜......T_T.. 为 Radix 感到难过......快速排序真的更快吗?

【问题讨论】:

  • 看来您可能误解了渐近复杂性...
  • 实际上,我是算法处女。如果你能解释这意味着什么,我将非常感激。
  • 您的样本量太小 - 请尝试对 5000 万个值进行排序。此外,执行的指令数量与性能之间没有一对一的关系。顺便问一下,您是如何确定执行的指令数的?
  • @500-InternalServerError with gdb & set break point & and some kinde gdb instructions
  • it turns out that quick sort has smaller number of instructions than quick sort. 哦。永远不要将大脑周期投入到低于 5 秒的计时结果中。

标签: algorithm


【解决方案1】:

快速排序通常是对数组进行排序时的最佳选择,尤其是当您没有关于数字范围的信息并且数组非常大时。这是因为 qsort 的预期时间复杂度与其输入大小乘以该大小的对数 O(nlogn) 成正比,这是基于比较的算法所能获得的最佳时间复杂度。此外,它有一个小的隐藏常数因子,并且排序到位。基数排序不通过比较进行排序,您需要了解输入的大小(n)和每个数字的平均位数(k),因为它的时间复杂度与 k*n 成正比。

在您的情况下,您有一个相当小的数组要进行测试,因此两种算法的行为之间的任何可观察到的差异都是渐近无关的。快速排序获胜是因为,如前所述,它在 O(nlogn) 中隐藏了一个小的常数运算因子。如果您尝试在一个小数组上运行插入排序和合并排序,尽管 InsSort 在最坏的情况下具有 O(n^2) 和 MergeSort O(nlogn),但插入排序很有可能会更快,同样原因同上。 但请放心,如果您在 10^8 个数字的数组上尝试它们,结果会发生很大变化。 另外请记住,没有最佳排序算法之类的东西,您只需要每次查看哪一个更适合您的问题性质。 :)

【讨论】:

    猜你喜欢
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 2011-11-30
    • 2018-05-24
    • 2017-03-18
    • 2021-07-27
    相关资源
    最近更新 更多