【问题标题】:Big O Notation for sorted insertion用于排序插入的大 O 表示法
【发布时间】:2014-10-09 21:19:09
【问题描述】:

以下是数组的 orderedInsertion 代码:

    public void orderedInsert(int x){
    int i =0;
    for(i=0;i<count;i++) if(arr[i]>x) break;
    for(int j=count-1;j>=i;j--) arr[j+1] = arr[j];
    arr[i]=x;
    count++;}

如果不是在 IF 语句之后使用 break,我确实实现了第二个 for 循环(带有 j 变量的循环如下: 编辑代码:

    public void orderedInsert(int x) {
        boolean flag = false;
        int i =0;
        for (i=0; i<count; i++) { 
            if (arr[i]>x) {
                for (int j=count-1; j>=i; j--) {
                    arr[j+1] = arr[j];
                    arr[i] = x;
                    count++;
                    flag = true;
                }
                if (flag) 
                    break;
            }
        }
    }

两种算法都会在 O(N) 中运行吗?这对我来说是有意义的,但我的导师说“如果你看到两个嵌套循环,这意味着它运行 O(N^2)。

对我来说有意义的是,即使在最坏的情况下,我们也只会遍历 N 次。

【问题讨论】:

  • 你是对的。在大多数带有嵌套循环的代码中,外循环执行一定次数,而内循环也会执行一定次数次外循环执行,所以次数为O(N^2) 或 O(M*N)。但是,在这种情况下,您只能到达内部 for 一次——而不是每次执行外部循环时都访问一次。因此,您的老师所说的不适用于这种情况。附言你不需要flag——你可以在if里面break
  • PPS。正确缩进你的代码对于读者(和你的导师)了解发生了什么很有帮助。
  • 您在重写方法(第 2 块)中的代码有 2 个左大括号 {,但 3 个右大括号 },并带有当前支撑您的if(flag)break; 不在循环内,所以什么也不做。
  • 我没有注意到——显然代码缺少{。所以 实际 代码看起来是 O(N^2) (并且可能根本不能正常工作),但 intended 代码应该是 O(N)。 (或者我们应该说实际代码是 O(1),因为它不会编译。)我想我按照您的意思阅读代码,而不是错误地编写代码。
  • 我已经更新了 OP 中的代码。这是我没有在 Eclipse 中编写的快速编辑,对此感到抱歉。

标签: java


【解决方案1】:

在这种情况下,这两种算法似乎是 O(n),即使它们并不相似。 Count 的使用方式不同,看起来第一个使用 count 可能是为了显示它更改的数组的大小。因此,如果有人将一个元素放入数组中,则计数会增加。但第二种用途算作其他用途。 arr[i] = x; 也一样。第一个似乎设置了一次,而第二个继续设置它。

嵌套循环的典型情况如下:

  for(int j=count-1;j>=i;j--) 

如果count = 100

   for(int j=100-1;j>=0;j--) // 100 times it must iterate 

  //then i turns to 1

  for(int j=100-1;j>=1;j--) //must iterate 99 times

   etc...

如果它只是一个循环,它将只迭代 100 次

 for(i=0;i<count;i++) //iterate 100 times that is it, its done

但是使用嵌套循环它会迭代

when i=0 : it iterates 100 times
when i=1 : it iterates 99 times
when i=2 : it iterates 98 times 

换句话说,如果这里只有一个循环,它只会迭代 100 次 但是对于这个嵌套循环,它循环了 100 次 + 99 次 + 98 次等。这很可能尤其是 'if(arr[i]>x) break;'永远不会发生

同样根据Big Oh notation,如果某件事需要 (n(n-1))/2 次才能完成,那么它就被认为是 O(n^2)

【讨论】:

  • 但是break语句呢?假设 i = 3,我们找到了目标。到目前为止我们已经迭代了 3 次,J 循环将迭代 97 次,然后中断!我们只迭代了 100 次,这将等于 N。
  • @Lifter for(i=0;ix) break;如果 arr[i] 永远不会大于 x 怎么办。所以迭代整个事情 n^2 次。使用大 O 表示法意味着这段代码的最坏情况是什么。
  • @Rika 如果arr[i] 永远不会大于x,则永远不会启动内部循环,因此时间为 O(N)。我编辑了原始帖子以改进格式,并且 OP 添加了一个缺失的{,这样可以更容易地看到发生了什么。这可能更清楚代码实际上是 O(N),因为内部 for 不会多次启动,除非它可能立即终止。
  • @ajb 对于他编写的第一个代码,将开始内部循环,因为没有括号,因此它将循环第一个循环,然后是第二个循环。所以在那种情况下如果count = 100,它会循环100次,然后再循环100次。
  • @Rika 我不明白--第一个算法没有嵌套循环,怎么可能是O(N^2)?
猜你喜欢
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-03-18
  • 2021-06-30
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
相关资源
最近更新 更多