Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何计算这个递归函数的时间复杂度?(英国夏令时)_C_Recursion_Tree_Binary - Fatal编程技术网

C 如何计算这个递归函数的时间复杂度?(英国夏令时)

C 如何计算这个递归函数的时间复杂度?(英国夏令时),c,recursion,tree,binary,C,Recursion,Tree,Binary,我在计算我为任务编写的函数的时间复杂度时遇到了一些问题 此函数是递归函数,它统计二进制搜索树中值大于10的叶数。以下是函数: int count_leaf(node* root) { static int count = 0; int call; if (root == NULL) { return 0; } call = count_leaf(root->left); if (root->left == NULL &&

我在计算我为任务编写的函数的时间复杂度时遇到了一些问题

此函数是递归函数,它统计二进制搜索树中值大于10的叶数。以下是函数:

int count_leaf(node* root)
{
  static int count = 0; 
  int call; 
  if (root == NULL) 
   {
     return 0;
   }
  call = count_leaf(root->left);
  if (root->left == NULL && root->right == NULL && root->data > 10)
   {
     count++;
   }
  call = count_leaf(root->right); 
  return count;
}

计算此函数时间复杂度的最正确方法是什么?

它只触及树的每个节点一次,因此将有
n
调用,使其
O(n)

复杂度实际上是
O(n)
,因为您需要访问所有节点。这比与二叉树关联的
O(n*logn)
更好。它也是渐近最优的


子节点直接从父节点访问,而不是从根节点访问,依此类推,对于每个子节点,以这种方式访问子节点是一个固定时间操作。当遍历完成时,所有
n
节点都已被访问。

一种通过实验测量算法实现复杂性的简单方法是将计数器放在用于迭代的函数或循环的开头。对于您的示例,如下所示:

int test_count = 0;

int count_leaf(node* root)
{
  static int count = 0; 
  int call; 

  ++test_count;

  // ...

}
然后在运行测试后打印出
test\u count
的值。如果您使用不同的测试集进行实验(使每个测试集的大小增加一倍,以使差异变得明显),您将得到一个很好的指示,表明算法是否为O(1)、O(n)、O(n^2)等

另一种方法是使用简单的计时器来测量测试运行的持续时间。将运行算法的时间与几个大小加倍的数据集进行比较。处理每个数据集所需时间的差异将显示算法的计算复杂性。参见Sedgewick的“算法”第四版第1.4节,了解一些示例


显然,这些都不是证明,对于大多数家庭作业答案来说可能是不可接受的,但它可以帮助您确保获得正确的家庭作业答案。

所以它会遍历所有节点,对吗?有多少节点?嗯,树中有多少节点重要吗?据我所知,这对于计算时间复杂度来说是无用的信息,但好吧,假设你知道处理一棵特定的树需要多长时间。如果向该树中再添加一个节点,则预计需要多长时间?如果尝试多次调用函数,则实现将中断。在特定任务中,a不需要多次调用它。但是如果是的话,我可以将这个计数器定义为一个全局变量,并且每次在函数调用之前将其初始化为零。谢谢!没有办法优化它,对吗?因为我几乎必须检查每个叶子是否有大于10的值…实际上有…想想二叉搜索树中的节点是如何排列的。这与它们的值有什么关系呢?如果您将随着时间的推移对各种值进行多次检查,那么将计算时间用于从二叉树创建二叉搜索树(BST)可能是有意义的。一旦你有了一个构造良好的(有点平衡的)BST,每个调用将花费~O(logN)时间而不是~O(N)。IMHO,这取决于你感兴趣的时间复杂度-最坏的情况?平均值?另一种可能性(您可能不在寻找,但只是以防万一…)是缓存您感兴趣的叶子。几个问题:在变量名之前标记递增是否重要?我如何在不使用静态或全局计数器的情况下实现这个函数?我看不出用另一种方法解决这个问题的正确方法:(由于增量计算没有作为更大表达式的一部分使用,因此哪种类型的增量的细节并不重要。
test\u count++
test\u count++=1
、或者
test\u count=test\u count+1
在这里都可以很好地工作。我认为没有全局计数器,就没有一种简单、干净的方法来使用计数器这种方法实际上只是为了实验。