简体   繁体   English

递归算法的时间复杂度

[英]Time complexity of algorithm with recursion

I have the following: 我有以下内容:

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;
}

This essentially sorts an array 'A' of length 'n'. 这实质上是对长度为'n'的数组'A'进行排序。 However, after trying to figure out what the time complexity of this algorithm, I keep running into circles. 但是,在尝试弄清楚该算法的时间复杂度之后,我不断陷入困境。 If I take a look at the first while-loop, the content in the loop will get execute 'n-2' times, thus making it O(n). 如果我看一下第一个while循环,循环中的内容将被执行'n-2'次,从而使其为O(n)。 The second while-loop executes in 'n-1' times, thus making it O(n), provided we've dropped the constants for both functions. 第二个while循环在'n-1'次执行,因此使其为O(n),前提是我们删除了两个函数的常量。 Now, the recursive portion of this algorithm is what throws me off again. 现在,该算法的递归部分再次使我失望。

The recursion looks to be tail-recursive given that it doesn't call anything else afterwards. 递归看起来是尾递归,因为它之后没有再调用其他任何东西。 At this point, I'm not sure if the the recursion being tail-recursive has anything to do with this time complexity... If this is really an O(n) does this necessarily mean that it's Omega(n) as well? 在这一点上,我不确定尾递归的递归是否与此时间复杂度有关...如果这确实是O(n),是否必然意味着它也是Omega(n)?

Please correct any of my assumptions I've made if there are any. 如果有的话,请更正我所做的任何假设。 Any hints would be great! 任何提示都很棒!

This is O(n 2 ). 这是O(n 2 )。

This is because with each recursion, you iterate the entire array twice. 这是因为每次递归都将整个数组迭代两次。 Once up (bubbling the highest answer to the top) and once down (bubbling the lowest answer to the bottom). 一次向上(使最高答案出现在顶部),一次向下(使最低答案出现在底部)。

On the next iteration, you have yet another 2n. 在下一次迭代中,您还有2n。 However, we know the topmost and bottommost elements are correct. 但是,我们知道最上面和最下面的元素都是正确的。 Because of this we know we have n-2 unsorted elements. 因此,我们知道我们有n-2个未排序的元素。 When it repeats, you will sort 2 more elements, and so on. 重复时,您将再排序2个元素,依此类推。 if we want to find the number of iterations, "i", then we solve for n - 2i = 0. i = n/2 iterations. 如果要查找迭代次数“ i”,则求解n-2i =0。i = n / 2迭代。

n/2 iterations * 2n operations per iteration = n 2 operations. n / 2次迭代*每次迭代2n次操作= n 2次操作。

EDIT: tail recursion doesn't really help with time order, but it DOES help some languages with memory processing. 编辑:尾部递归对时间顺序并没有真正的帮助,但是它确实可以帮助某些语言进行内存处理。 I can't say exactly how it works, but it significantly reduces the stack space required somehow. 我不能确切地说出它是如何工作的,但是它以某种方式大大减少了所需的堆栈空间。

Also, I'm a bit rusty on this, but O notation denotes WORST case, whereas Omega notation denotes BEST case. 另外,对此我有点生锈,但是O表示最坏的情况,而Omega表示最佳的情况。 This is Omega(n), because the best case is that it iterates the array twice, finds everything is sorted, and doesn't recurse. 这是Omega(n),因为最好的情况是对数组进行两次迭代,发现所有内容都已排序,并且不会递归。

In your case the recurrence relation is something like: 在您的情况下,递归关系类似于:

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

But if we assume the biggest no. 但是,如果我们假设最大的拒绝。 will end up at the end in every case. 在每种情况下都将最终结束。 We can approximate: 我们可以近似得出:

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

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

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

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

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

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

If nk = 1 如果nk = 1

then k = n+1 substitutuing that 然后k = n + 1代入

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

order O(n^2) 阶O(n ^ 2)

Also smallest no. 也是最小号 will end up at the begining so we could also have approximated. 将在开始时结束,因此我们也可以近似。

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

Still order would be O(n^2) 仍然是O(n ^ 2)

If that approximation is removed we can't estimate exactly when done will be true. 如果删除了该近似值,我们将无法准确估计何时完成。 But in this case we can be sure that the biggest no will always end up at the end after each iteration and the smallest at the beginning so nothing would be done for 0 and n-1. 但是在这种情况下,我们可以确保最大的no总是在每次迭代结束后结束,而最小的no在开始时结束,因此对于0和n-1不会做任何事情。

I hope this helps you understand why n^2. 希望这可以帮助您理解为什么n ^ 2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM