【问题标题】:Computing the nodes of a left skewed tree faster更快地计算左倾斜树的节点
【发布时间】:2021-10-01 08:42:37
【问题描述】:
我必须遍历一棵树,我需要计算其中的节点总数。所以,以一种更简单的方式,我可以遍历树并做一些 count++ 来计算树的节点。但这对于具有数百万个节点的树来说非常耗时。这将花费 O(N) 时间,其中 N 是节点数。我想降低这种方法的时间复杂度。我怎样才能做到这一点?供你参考,我分享我的想法的伪代码。
struct Node{
Node* left;
Node* right;
}
int traverse(Node* node){
if (node == null) return 0; //base case
count++;
count += traverse (node->left) //recursive call
count += traverse (node->right) //recursive call
return count;
}
另外请让我知道上述方法是否可行?如果不是那为什么?请提出任何更快的方法。
【问题讨论】:
标签:
data-structures
tree
time-complexity
recursive-datastructures
【解决方案1】:
没有其他方法可以计算节点,即你必须访问它们。但是您的递归函数中有一个未声明的变量count。而是在每次调用中从头开始,因为您将只返回该节点 below 的节点数(以及 1 来说明节点本身),而不管该节点的其他环境如何: p>
int traverse(Node* node){
if (node == null) return 0; //base case
return 1 + traverse(node->left) + traverse(node->right);
}
但是,如果您要在树的不同状态下重复计算节点数,那么您可能会受益于存储每个子树中的节点数,并随着那个树。因此,您将在每个节点实例中存储以它为根的子树中的节点数(包括其自身)。
struct Node{
Node* left;
Node* right;
int count;
}
对于每个插入操作,您都会增加该节点所有祖先的count 成员,并将节点本身的计数设为 1。这表示 O(logn) 时间复杂度,它不会增加您可能的时间复杂度已经有用于插入操作。
对于每个删除操作,您都会减少该已删除节点的所有祖先的 count 成员。这表示 O(logn) 时间复杂度,不会增加您可能已经拥有的删除操作的时间复杂度。
当需要获取整棵树的计数时,只需读出根节点的count值即可。那么这只是一个 O(1) 操作。