Java 递归算法的时间复杂度

Java 递归算法的时间复杂度,java,data-structures,time-complexity,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;

我有以下资料:

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;
}
公共静态int[]MyAlgorithm(int[]A,int-n){
布尔完成=真;
int j=0;
while(ja[j+1]){
内部温度=A[j+1];
A[j+1]=A[j];
A[j]=温度;
完成=错误;
}
j++;
}
j=n-1;
而(j>=1){
if(A[j]
这实际上是对长度为“n”的数组“A”进行排序。然而,在试图弄清楚这个算法的时间复杂度之后,我一直在兜圈子。如果我看一下第一个while循环,循环中的内容将执行'n-2'次,从而使其成为O(n)。第二个while循环以'n-1'次执行,从而使其成为O(n),前提是我们删除了这两个函数的常量。现在,这个算法的递归部分又让我感到厌烦了

递归看起来是尾部递归的,因为它之后不调用任何其他东西。在这一点上,我不确定作为尾部递归的递归是否与时间复杂性有关。。。如果这真的是一个O(n),这是否意味着它也是ω(n)

如果有任何假设,请纠正我的假设。任何提示都很好

这是O(n2)

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

在下一次迭代中,您还有另一个2n。然而,我们知道最上面和最下面的元素是正确的。因此,我们知道有n-2个未排序的元素。当它重复时,您将对另外两个元素进行排序,依此类推。如果我们想找到迭代次数“i”,那么我们求解n-2i=0。i=n/2次迭代

n/2次迭代*2n次迭代操作=n2次操作

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


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

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

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。

您的代码看起来是错误的,因为递归总是使用相同的值。。。我希望一到两个元素与代码一起进入它们的位置,递归中的范围更小(以O(n^2)结尾),我很难理解n/2迭代的来源。我知道这两个循环的复杂性使它成为O(2n)=O(n),但我们为什么要将迭代次数减少2,这是一个模糊的问题……每次迭代都会对最外层的元素进行排序。有底部元素和顶部元素,导致“n个元素中的2个”被排序。一旦元素冒泡到了正确的位置,就不会像编写算法那样再次接触它。因此,在最坏的情况下,每个迭代对2个元素进行排序。对“n”个元素进行排序需要多少次迭代?这个问题的答案是如何得到“n/2”迭代。啊!因此,在这种情况下,递归调用将被调用n/2次,因为每次传递对两个元素进行排序,对吗?另外,可以安全地说递归会影响(#堆栈帧或递归调用)x(递归调用前内容的时间复杂度)给出的时间复杂度吗?否。在这种情况下是正确的,因为每个递归的步骤数是相同的。但在某些情况下,分治算法可能会在每次递归中采取较少的步骤。例如,第一次通过可能需要所有的“n”元素,但下一次通过可能只需要一半,下一次甚至需要一半。n+n/2+n/4+n/8…=2n=O(n)