要找到算法的运行时间,我们首先需要能够为算法编写一个表达式,该表达式告诉每个步骤的运行时间。因此,您需要遍历算法的每个步骤才能找到表达式。
例如,假设我们定义了一个谓词 isSorted,它将一个数组 a 和数组的大小 n 作为输入,并且当且仅当数组按升序排序时才返回 true。
bool isSorted(int *a, int n) {
if (n == 1)
return true; // a 1-element array is always sorted
for (int i = 0; i < n-1; i++) {
if (a[i] > a[i+1]) // found two adjacent elements out of order
return false;
}
return true; // everything's in sorted order
}
很明显,这里输入的大小只是数组的大小 n。对于输入 n,在最坏情况下将执行多少步?
第一个 if 语句计为 1 步
for循环在最坏的情况下将执行n-1次(假设内部测试没有把我们踢出去),循环测试和索引增量的总时间为n-1 .
在循环内部,还有另一个 if 语句,每次迭代都会执行一次,总共 n-1 次,最坏的情况。
最后一次返回会执行一次。
所以,在最坏的情况下,我们将完成 1+(n−1)+(n−1)+1
计算,对于总运行时间 T(n)≤1+(n-1)+(n-1)+1=2n,因此我们有时序函数 T(n)=O(n)。
简而言之,我们所做的是-->>
1.对于给出输入大小的参数'n',我们假设每个执行一次的简单语句将花费恒定时间,为简单起见假设一个
2.循环和内部正文等迭代语句将根据输入的不同花费不同的时间。
它有解 T(n)=O(n),就像非递归版本一样。
3.所以你的任务是一步一步地写下n的函数来计算时间复杂度
对于递归算法,您执行相同的操作,只是这次您添加了每个递归调用所花费的时间,表示为它在其输入上花费的时间的函数。
比如我们重写一下,isSorted为递归算法:
bool isSorted(int *a, int n) {
if (n == 1)
return true;
if (a[n-2] > a[n-1]) // are the last two elements out of order?
return false;
else
return isSorted(a, n-1); // is the initial part of the array sorted?
}
在这种情况下,我们仍然遍历算法,计算:第一个 if 1 步加上第二个 if 1 步,加上时间 isSorted 将采用大小为 n−1 的输入,即 T(n -1),给出递归关系
T(n)≤1+1+T(n-1)=T(n-1)+O(1)
有解 T(n)=O(n),就像非递归版本一样。
够简单!!练习更多写各种算法的递归关系记住算法中每个步骤将执行多少时间