【问题标题】:Big o of insertion sort algorithm: iterative and recursive插入排序算法的大o:迭代和递归
【发布时间】:2016-03-18 01:18:22
【问题描述】:

这里我有两种插入排序算法。我很难找出这两种插入排序形式的大 O。我有一个迭代形式和一个递归形式。我说迭代形式是 n^2 而递归形式是 n^2 是不是错了。如果我错了,它们是什么,为什么?你是怎么得出这个答案的?

  public void iterativeSort(int[] list) {
        start = System.currentTimeMillis();
        for (int i = 1; i < list.length; i++) {
            count++;
            int temp = list[i];
            int j;

            for (j = i - 1; j >= 0 && temp < list[j]; j--) {
                list[j + 1] = list[j];
            }

            list[j + 1] = temp;
            finish += System.currentTimeMillis() - start;
        }

    }

    public static void recursiveSort(int array[], int n, int j) {
        finish += System.currentTimeMillis() - start;
        start = System.currentTimeMillis();
        if (j < n) {

            int i;
            count++;
            int temp = array[j];

            for (i = j; i > 0 && array[i - 1] > temp; i--) {
                array[i] = array[i - 1];
            }

            array[i] = temp;

            recursiveSort(array, n, j + 1);
        }
    }

【问题讨论】:

标签: java algorithm sorting recursion insertion-sort


【解决方案1】:

是的,你说得对,这两种实现都需要O(n^2) 时间。您不可能通过从递归实现切换到迭代实现来减少算法的运行时间,反之亦然。但是,这适用于空间使用情况。

如何确定运行时间是O(n^2)。迭代解决方案更容易和更明显。通常,当您嵌套了 for-loops 而没有任何特定的中断条件并且您正在运行一小部分线性元素时,运行时间是二次的。让我们进一步分析它。 for (int i = 1; i &lt; list.length; i++) 中的条件将评估多少次 true?答案是n-1,因为您从第二个元素开始直到结束。例如,如果n=5,则条件将是true for i = 1, 2, 3, 4(由于基于0 的索引),正好是n-1 次,在本例中表示4。现在内部循环条件将计算多少次到true?在第一次运行时,它将执行一次,因为 i = 1j = 0 并且在一次迭代之后 j 将是 -1 这将打破条件。在第二次迭代中,它将执行两次,第三次执行三次,以此类推,最多 n - 1 次。所以我们基本上得到的是和1 + 2 + 3 + ... + (n - 1),你可以很容易地证明它等于(n-1)n/2)。由于您在 big-O 中删除常量,因此运行时间为 O(n^2)

现在对第二个实现的分析可能会因为递归而显得有些复杂,但实际上并没有太大的不同。内部循环for (i = j; i &gt; 0 &amp;&amp; array[i - 1] &gt; temp; i--) 的逻辑几乎相同,因为它执行一次,j = 1,两次j = 2 等等。我们将递归调用该方法多少次?再次n - 1 次,因为第一个调用是j = 1,因此是j &lt; n(假设n 很大),然后调用recursiveSort(array, n, j + 1);。现在j = 2 再次小于n,所以我们将递归调用函数直到j == n,所以正好是n - 1 次。鉴于内部循环嵌套在O(n) 中,我们得到相同数量的迭代,即1 + 2 + 3 + ... + ( n-1 ) 再次导致O(n^2)

所以我们非正式地证明了这两种算法具有相同的渐近运行时间。在这种情况下,我们可以认为它们是等价的吗? 。这是因为每个递归调用都会在堆栈上保留额外的空间,这意味着递归解决方案占用O(n) 空间,而迭代解决方案占用O(1)。从这个意义上说,我们可以说迭代解决方案更好,这通常是这种情况,但递归解决方案可能更具可读性(这里不是这种情况)。

【讨论】:

  • 感谢您的回复。我认为这有助于我理解问题。
  • 我很高兴能帮上忙。 Big-O 是初学者经常遇到的问题,所以如果您不详细了解所有内容,请不要害怕。我试图尽可能精确,但实际上你需要一些时间来真正习惯它并真正理解它。
猜你喜欢
  • 2020-09-23
  • 2011-01-19
  • 2011-02-08
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
相关资源
最近更新 更多