【问题标题】:How to check Big O notation of a sorting algorithm?如何检查排序算法的大 O 表示法?
【发布时间】:2021-06-30 13:53:23
【问题描述】:

我不知道如何解决它的复杂性等问题。如何知道它是否比其他排序算法更快?

我觉得很难找到它,因为我的数学有点差。

#include <stdio.h>

int func(int arr[])
{
    int temp;
    int numofarrays=9999;
    for(int runtime=1; runtime<=numofarrays/2; runtime++)
    {
        for(int i=0; i<=numofarrays; i++)
        {
            if(arr[i] > arr[i+1])
            {
                temp=arr[i];
                arr[i]=arr[i+1];
                arr[i+1]=temp;
            }
            if(arr[numofarrays-i-1] > arr[numofarrays-i])
            {
                temp=arr[numofarrays-i-1];
                arr[numofarrays-i-1]=arr[numofarrays-i];
                arr[numofarrays-i]=temp;
            }
        }

    }
    for(int i=0; i<=9999; i++)
    {
        printf("%i\n",arr[i]);
    }
}
int main()
{
    int arr[10000];
    for(int i=0; i<=9999; i++)
    {
        arr[i]=rand() % 10;
    }

    func(arr);
}

【问题讨论】:

  • 你可以衡量它是否比其他算法更快。
  • 因为您的排序函数使用嵌套循环(一个 for 循环在另一个循环中)。它的复杂度为 O(n^2)。您似乎正在使用冒泡排序算法。有很多other sorting algorithms that are way faster than bubble sort
  • 您的算法越界访问数组,这是未定义的行为。

标签: c algorithm sorting time-complexity big-o


【解决方案1】:

经验方法是为n 的给定输入计时 (t) 您的算法。然后对更大和更大的n 进行该实验,例如,从n = 020 的 2^n。在图表上绘制 (2^n, t)。如果你得到一条直线,那就是线性算法。如果你得到一些增长更快的东西,试试图表ln(t),看看你是否得到一条线,那将是一个指数算法,等等。

分析方法看起来很可怕,有时数学很繁重,但实际上并非必须如此。你决定你的昂贵操作是什么,然后你计算你做了多少。任何在循环中运行的东西(包括递归函数)都是主要候选对象,其运行时间会随着循环运行次数的增加而增加:

  1. 假设我们要计算交换次数。
  2. 内部循环交换numofarrays 次,即O(n)
  3. 外部循环运行 numofarrays/2 次,这也是 O(n),因为我们将系数降低了 1/2,因为当 n 变大时并不重要。
  4. 这意味着我们进行 O(n) * O(n) = O(n^2) 交换次数。
  5. 您的打印循环没有进行任何交换,因此我们认为它们是“免费的”,但如果确定它们与交换一样昂贵,那么我们也想计算它们。您的算法执行numofarrays 打印操作,即O(n)
  6. O(n^2) + O(n) 只是 O(n^2),因为较大的 O(n^2) 支配 O(n) 以获得足够大的 n

【讨论】:

    【解决方案2】:

    大 o 符号是您编写的代码的步数限制到无穷大的地方。由于极限趋于无穷大,我们忽略系数并查看最大值。

    for(int runtime=1; runtime<=numofarrays/2; runtime++)
    {
        for(int i=0; i<=numofarrays; i++)
        {
    

    这里,第一个循环的最大项是n,第二个循环的最大项是n。但是由于循环 2 为第一个循环的每一圈转 n 圈,所以我们将 n 乘以 n。 结果是 O(n^2)。

    【讨论】:

      【解决方案3】:

      这里:

      for(int runtime=1; runtime<=numofarrays/2; runtime++)
      {
          for(int i=0; i<=numofarrays; i++)
          {
      

      您有两个嵌套的for 循环,它们都取决于数组的大小。所以复杂度是O(N^2)。

      你还问:

      如何知道它是否比其他排序算法更快?

      big-O 不会直接告诉您执行时间。对于某些 N 值,O(N) 实现可能比 O(N^2) 实现慢。

      Big-O 告诉您执行时间如何随着 N 的增加而增加。所以你知道当 N 超过一个特定值时 O(N^2) 会比 O(N) 慢,但你不知道那个值是什么!可以是 1、5、10、100、1000,...

      例子:

      【讨论】:

      • 漂亮的图表。如果你做了,你能用 lg(n) 做另一个,所以 op 可以看到它是一条线吗?可能是 n^2 和 n^3。
      猜你喜欢
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 2020-05-01
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多