递归算法的时间复杂度

时间:2015-09-25 03:31:39

标签: java data-structures time-complexity

我有以下内容:

public static int[] MyAlgorithm(int[] A, int n) {
    boolean done = true;
    int j = 0;
    while(j <= n - 2) {
        if(A[j] > A[j+1]) {

            int temp = A[j + 1];
            A[j + 1] = A[j];
            A[j] = temp;

            done = false;
        }
        j++;
    }
    j = n - 1;
    while(j >= 1) {
        if(A[j] < A[j-1]) {
            int temp = A[j - 1];
            A[j - 1] = A[j];
            A[j] = temp;
            done = false;
        }
        j--;
    }

    if(!done)
        return MyAlgorithm(A, n);
    else 
        return A;
}

这基本上对长度为'n'的数组'A'进行排序。但是,在试图弄清楚这个算法的时间复杂度之后,我不断碰到圈子。如果我看一下第一个while循环,循环中的内容将执行'n-2'次,从而使其成为O(n)。第二个while循环在'n-1'次执行,因此只要我们删除了两个函数的常量就使它成为O(n)。现在,这个算法的递归部分再次引发了我的兴趣。

递归看起来是尾递归的,因为它之后不会调用任何其他东西。此时,我不确定尾递归的递归是否与这个时间复杂度有关...如果这真的是O(n)这是否也意味着它也是Omega(n)?

如果有的话,请更正我所做的任何假设。任何提示都会很棒!

2 个答案:

答案 0 :(得分:4)

这是O(n 2 )。

这是因为每次递归都会迭代整个数组两次。一旦上升(将最高的答案冒泡到顶部)并一次向下(将最低的答案冒泡到底部)。

在下一次迭代中,你还有另一个2n。但是,我们知道最顶层和最底层的元素是正确的。因此我们知道我们有n-2个未排序的元素。重复时,您将再排序2个元素,依此类推。如果我们想要找到迭代次数,那么我们求解n - 2i = 0. i = n / 2次迭代。

n / 2次迭代*每次迭代2n次操作= n 2 操作。

编辑:尾递归对时间顺序没有帮助,但是它可以帮助一些语言进行内存处理。我不能确切地说它是如何工作的,但是它以某种方式显着减少了所需的堆栈空间。

另外,我对此有点生疏,但O表示法表示最坏情况,而欧米茄表示法表示最佳情况。这是Omega(n),因为最好的情况是它迭代数组两次,发现所有内容都已排序,并且没有递归。

答案 1 :(得分:1)

在您的情况下,递归关系类似于:

T(n)= T(n)+ n。

但如果我们假设最大的没有。 在每种情况下都会最终结束。我们可以近似:

T(n)= T(n-1)+ n

T(n-1)= T(n-2)+ n-1

t(n-2)= T(n-3)+ n-2

T(n)= T(n-2)+ n-1 + n

T(n)= T(n-3)+ n-2 + n-1 + n

T(n)= T(n-k)+ kn -k(k-1)/ 2

如果n-k = 1

然后k = n + 1 替代

T(n)= T(1)+ n(n + 1) - (n + 1)(n)/ 2

订单O(n ^ 2)

也是最小的没有。将在开始时结束,所以我们也可以近似。

T(n)= T(n-2)+ n

仍然是O(n ^ 2)

如果删除了该近似值,我们无法准确估计何时 完成将是真的。但在这种情况下,我们可以肯定最大的没有 在每次迭代后总是会在最后结束,而在开始时最小,所以不会为0和n-1做任何事情。

我希望这可以帮助你理解为什么n ^ 2。