简体   繁体   English

算法的通用方式的时间复杂度推导过程

[英]Time-complexity derivation procedure in generic way for algorithms

I have been reading a lot of articles on data structures and algorithms and everyone only says the most generic way of calculating the time complexity and is usually defined as the time taken for the execution considering variations in input and to iterate an array of n elements let the code be as below and the Big-O complexity is O(n).我一直在阅读很多关于数据结构和算法的文章,每个人都只说最通用的计算时间复杂度的方法,通常被定义为考虑输入变化的执行时间和迭代 n 个元素的数组,让代码如下,Big-O 复杂度为 O(n)。

 for (int i=0;i<a.length;i++)
   System.out.println(a[i]);

Agreed thats the way of calculating the time complexity but what about recursive algorithms and how does one come to the conclusion of logarithmic expressions and stuff while calculating time complexity.同意这是计算时间复杂度的方法,但是递归算法如何以及在计算时间复杂度时如何得出对数表达式和东西的结论。 There is no standard that I came across or aware of so far for deriving those complexities.到目前为止,我还没有遇到或意识到推导出这些复杂性的标准。 If yes can someone please throw some light or refer me where to start.如果是的话,有人可以提出一些意见或告诉我从哪里开始。

Thanks in advance.提前致谢。 Please don't mark as duplicate as there could be many who are facing the same issue of understanding and derving time-complexities after getting tired from different tutorials on web.请不要将其标记为重复,因为可能有许多人在从网络上的不同教程中厌倦后面临同样的理解问题和推导时间复杂性的问题。

Unfortunately, there's no general-purpose algorithm you can follow that, given an arbitrary piece of code, will tell you its time complexity.不幸的是,没有您可以遵循的通用算法,给定任意一段代码,它会告诉您它的时间复杂度。 This is due, in part, to the fact that there's no general way to determine whether an arbitrary piece of code will even halt in the first place.这部分是因为没有通用的方法来确定任意一段代码是否会首先停止 If we could take an arbitrary piece of code and work out its time complexity - assuming it even has one - we could potentially use that to determine whether it would terminate, and that's not something we can do.如果我们可以采用任意一段代码并计算出它的时间复杂度——假设它甚至有一个——我们可能会使用它来确定它是否会终止,而这不是我们可以做的。

As an example of why this is hard, consider this piece of code:作为为什么这很难的一个例子,请考虑这段代码:

int n = /* get user input */
while (n > 1) {
    if (n % 2 == 0) n /= 2;
    else n = 3*n + 1;
}

This code traces out the "hailstone sequence" starting at the user's number n.此代码从用户编号 n 开始追踪“冰雹序列”。 Surprisingly, no one knows whether this process always terminates , and so no one currently has any upper bound at all on how many steps this loop is going to take to terminate.令人惊讶的是,没有人知道这个过程是否总是终止,所以目前没有人知道这个循环将采取多少步骤来终止。

In practice, working out how long a piece of code takes to run requires a mix of different techniques.在实践中,计算一段代码运行需要多长时间需要混合使用不同的技术。 For example, the Master Theorem is helpful in determining how long it takes for many recursive functions to terminate.例如, 主定理有助于确定许多递归函数终止所需的时间。 For other, more complex recursive functions, we can often write out a recurrence relation for the runtime, then use a battery of techniques to solve those recurrences.对于其他更复杂的递归函数,我们通常可以写出运行时的递归关系,然后使用一系列技术来解决这些递归。 Sometimes it's helpful to work from the inside out, replacing inner loops with simpler expressions and seeing what comes out.有时从内到外工作很有帮助,用更简单的表达式替换内部循环,然后看看结果如何。 Sometimes, it's important to know useful summations like 1/1 + 1/2 + 1/3 + ... + 1/n = Θ(log n), or that 2 0 + 2 1 + ... + 2 k = Θ(2 k ).有时,了解一些有用的求和很重要,例如 1/1 + 1/2 + 1/3 + ... + 1/n = Θ(log n),或者 2 0 + 2 1 + ... + 2 k = Θ( 2k )。 Sometimes, you work out the runtime by thinking about how the code works and what each step does.有时,您通过考虑代码的工作方式以及每个步骤的作用来计算运行时。 And sometimes, it takes years to work out just how fast a piece of code is.有时,计算一段代码的速度需要数年时间。

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

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