简体   繁体   English

仅查看算法代码即可计算时间复杂度

[英]Calculating time complexity by just seeing the algorithm code

I have currently learned the code of all sorting algorithms used and understood their functioning. 我目前已经学习了所有使用的排序算法的代码,并了解了它们的功能。 However as a part of these, one should also be capable to find the time and space complexity. 然而,作为这些的一部分,人们也应该能够发现时间和空间的复杂性。 I have seen people just looking at the loops and deriving the complexity. 我看到人们只是看着循环并推导其复杂性。 Can someone guide me towards the best practice for achieving this. 有人可以指导我实现最佳实践。 The given example code is for "Shell sort". 给定的示例代码用于“ Shell排序”。 What should be the strategy used to understand and calculate from code itself. 从代码本身理解和计算的策略应该是什么。 Please help! 请帮忙! Something like step count method. 有点像步数法。 Need to understand how we can do asymptotic analysis from code itself. 需要了解如何从代码本身进行渐进分析。 Please help. 请帮忙。

int i,n=a.length,diff=n/2,interchange,temp;
while(diff>0) { 
    interchange=0;
    for(i=0;i<n-diff;i++) {
        if(a[i]>a[i+diff]) { 
            temp=a[i];
            a[i]=a[i+diff];
            a[i+diff]=temp;
            interchange=1;
        }
    }
    if(interchange==0) {
        diff=diff/2;
    }
} 

Since the absolute lower bound on worst-case of a comparison-sorting algorithm is O(n log n) , evidently one can't do any better. 由于最坏情况下的比较排序算法绝对下限O(n log n) ,因此显然不能做得更好。 The same complexity holds here. 同样的复杂性在这里。

Worst-case time complexity : 最坏情况下的时间复杂度

1. Inner loop 1.内循环

Let's first start analyzing the inner loop: 让我们首先开始分析内部循环:

for(i=0;i<n-diff;i++) {
    if(a[i]>a[i+diff]) {
        temp=a[i];
        a[i]=a[i+diff];
        a[i+diff]=temp;
        interchange=1;
    }
}

Since we don't know much (anything) about the structure of a on this level, it is definitely possible that the condition holds, and thus a swap occurs. 由于我们在此级别上对a的结构了解不多(一无所知),因此肯定有条件成立,因此发生交换。 A conservative analysis thus says that it is possible that interchange can be 0 or 1 at the end of the loop. 因此, 保守的分析表明,在循环结束时interchange可能为01 We know however that if we will execute the loop a second time, with the same diff value. 但是我们知道,如果第二次使用相同的diff值执行循环。

As you comment yourself, the loop will be executed O(n-diff) times. 当您自己评论时,循环将执行O(n-diff)次。 Since all instructions inside the loop take constant time. 由于循环内的所有指令都需要固定的时间。 The time complexity of the loop itself is O(n-diff) as well. 循环本身的时间复杂度也是O(n-diff)

Now the question is how many times can interchange be 1 before it turns to 0 . 现在的问题是,在变为0之前,可以将1 interchange多少次。 The maximum bound is that an item that was placed at the absolute right is the minimal element, and thus will keep "swapping" until it reaches the start of the list. 最大界限是放置在绝对右边的项目是最小元素,因此将保持“交换”状态直到到达列表的开头。 So the inner loop itself is repeated at most: O(n/diff) times. 因此,内部循环本身最多重复:O(n / diff)次。 As a result the computational effort of the loop is worst-case: 结果,循环的计算工作量是最坏的情况:

O(n^2/diff-n)=O(n^2/diff-n)

2. Outer loop with different diff 2.具有不同diff外循环

The outer loop relies on the value of diff . 外循环依赖于diff的值。 Starts with a value of n/2 , given interchange equals 1 at the end of the loop, something we cannot prove will not be the case, a new iteration will be performed with diff being set to diff/2 . n/2值开始,在循环结束时给定interchange等于1 ,我们无法证明情况并非如此,将diff设置为diff/2会执行新的迭代。 This is repeated until diff < 1 . 重复该过程,直到diff < 1为止。 This means diff will take all powers of 2 up till n/2 : 这意味着diff将取2所有幂直到n/2

1 2 4 8 ... n/2

Now we can make an analysis by summing: 现在我们可以通过总结来进行分析:

log2 n
------
 \
 /      O(n^2/2^i-n) = O(n^2)
------
i = 0

where i represents *log 2 (diff) of a given iteration. 其中, i表示给定迭代的* log 2 (diff)。 If we work this out, we get O(n 2 ) worst case time complexity. 如果我们解决这个问题,我们将得到O(n 2最坏情况的时间复杂度。

Note (On the lower bound of worst-case comparison sort): One can proof no comparison sort algorithm exists with a worst-case time complexity of O(n log n) . 注意 (在最坏情况比较排序的下限上):可以证明不存在最坏情况时间复杂度为O(n log n)的比较排序算法。

This is because for a list with n items, there are n! 这是因为对于具有n个项目的列表,有n个! possible orderings. 可能的订单。 For each ordering, there is a different way one needs to reorganize the list. 对于每种订购,都有一种不同的方式来重组列表。

Since using a comparison can split the set of possible orderings into two equals parts at the best, it will require at least log 2 (n!) comparisons to find out which ordering we are talking about. 由于使用比较可以将一组可能的排序最好地分为两个相等的部分,因此至少需要进行log 2 (n!)个比较才能找出我们正在谈论的排序。 The complexity of log 2 (n) can be calculated using the Stirling approximation : log 2 (n)的复杂度可以使用斯特林近似来计算:

  n /\\ | | log(x) dx = n log n - n = O(n log n) \\/ 1 

Best-case time complexity: in the best case, the list is evidently ordered. 最佳情况下的时间复杂度:在最佳情况下,列表显然是有序的。 In that case the inner loop will never perform the if-then part. 在这种情况下,内部循环将永远不会执行if-then部分。 As a consequence, the interchange will not be set to 1 and therefore after executing the for loop one time. 结果, interchange将不会设置为1 ,因此在执行了一次for循环之后。 The outer loop will still be repeated O(log n) times, thus the time complexity is O(n log n) . 外循环仍将重复O(log n)次,因此时间复杂度为O(n log n)

Look at the loops and try to figure out how many times they execute. 查看循环并尝试找出它们执行了多少次。 Start from the innermost ones. 从最内在的开始。

In the given example (not the easiest one to begin with), the for loop (innermost) is excuted for i in range [0,n-diff] , ie it is executed exactly n-diff times. 在给定的示例中(不是最简单的示例),在范围[0,n-diff]对for循环(最内部)进行i运算,即,它正好执行n-diff次。

What is done inside that loop doesn't really matter as long as it takes "constant time", ie there is a finite number of atomic operations. 只要需要“恒定时间”,在该循环内完成的操作实际上并不重要,即,原子操作数量有限。

Now the outer loop is executed as long as diff>0 . 现在,只要diff>0就执行外循环。 This behavior is complex because an iteration can decrease diff or not (it is decreased when no inverted pair was found). 此行为很复杂,因为迭代可以降低diff或不降低(未找到反向对时降低)。

Now you can say that diff will be decreased log(n) times (because it is halved until 0), and between every decrease the inner loop is run "a certain number of times". 现在您可以说diff将减少log(n)次(因为减半直到0),并且在每次减少之间,内部循环都会“运行一定次数”。

An exercised eye will also recognize interleaved passes of bubblesort and conclude that this number of times will not exceed the number of elements involved, ie n-diff , but that's about all that can be said "at a glance". 训练有素的眼睛还将识别交错的冒泡通过,并得出结论,该次数不会超过所涉及元素的数量,即n-diff ,但这几乎可以“一目了然”。

Complete analysis of the algorithm is an horrible mess, as the array gets progressively better and better sorted, which will influence the number of inner loops. 对该算法的完整分析令人头疼,因为数组越来越好,排序越来越好,这将影响内部循环的数量。

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

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