您的第一个递归关系通常用于描述分治算法的运行时间。a
这里显示您将数据划分为多少部分,显示1/b
每个部分中使用了哪些原始数据,并f(n)
显示每个“级别”需要多少时间。例如,在 QuickSort 算法中,您将数据(数组或列表)分成 2 部分,每部分恰好是原始数据的一半(1/2),并且在划分的每个“级别”上,您需要遍历所有n
元素 1时间。所以递归关系是
T(n) = 2T(n/2) + n
(计算结果为 O(n * lg(n)))在二分搜索中,您将数据分为 2 部分,但只取其中 1 部分,并且每个“级别”上的时间是恒定的,因此关系是:
T(n) = T(n/2) + 1
但是,您在 C 中的函数不遵循分而治之的策略。相反,它演示了数学归纳法。您定义开始条件:如果l
等于NULL
,则长度为 0,如果l->next
等于NULL
(您还为列表中的 1 个元素定义条件)。然后定义一种归纳步骤 - 如果您知道第 (n - 1) 个元素的函数值,则定义如何计算第 n 个元素的函数。因此,知道第一个元素的函数值,您可以应用此规则并获取第二个元素的值,然后获取第三个元素的值,依此类推。
所以你可以看到归纳法本质上是递归算法。这里我们有 2 次需要考虑。首先是在起点(或终点 - 这取决于您查看列表的顺序)计算值的时间。在您的函数中,您只需返回此值,因此它是常量 ( C1
)。其次是迈出第一步的时间。在您的函数中,它也是常数 ( C2
)。直观地你应该看到这个算法的执行时间将是:
T(n) = C1, when n = 1
T(n) = T(n - 1) + C2, when n > 1
因此,除非n = 1
,您定义在元素上执行算法的n
时间到在元素上执行算法的时间n - 1
。在 BigO 表示法中,任何常数都定义为1
,并且不考虑 1 个元素的情况,因此您的最终递归关系为:
T(n) = T(n - 1) + 1
(计算结果为T(n) = T(n - 1) + 1 = T(n - 2) + 2 = ... = 1 + n
, 或O(n)
)
进一步阅读: