也许这个问题不属于,因为这本身并不是一个编程问题,如果是这种情况我会道歉。
我刚接受抽象数据结构的考试,并且有这个问题:
树节点的等级定义如下:如果你是树的根,你的等级是0.否则,你的等级是你父母的等级+ 1.
设计一种算法,计算二叉树中所有节点的总和。算法的运行时是什么时候?
我的回答我相信解决了这个问题,我的伪代码是这样的:
int sum_of_tree_ranks(tree node x)
{
if x is a leaf return rank(x)
else, return sum_of_tree_ranks(x->left_child)+sum_of_tree_ranks(x->right_child)+rank(x)
}
其中功能等级为
int rank(tree node x)
{
if x->parent=null return 0
else return 1+rank(x->parent)
}
它非常简单,树的等级总和是左子树的总和+右子树的总和+根的等级。
我相信这个算法的运行时是n^2
。我相信这是因为我们没有给出二元树是平衡的。它可能是树中有n
个数字,但也有n
个不同的"等级",因为在树中看起来像链表而不是树。所以要计算一个叶子的等级,我们可能会提高一步。叶子的父亲将是n-1步骤等......所以n+(n-1)+(n-2)+...+1+0=O(n^2)
我的问题是,这是正确的吗?我的算法能解决问题吗?我对运行时的分析是否正确?最重要的是,有没有更好的解决方案来解决这个问题,而不是n^2
?
答案 0 :(得分:1)
您的算法有效。你的分析是正确的。这个问题可以在O(n)时间内解决:(自己照顾叶子)
int rank(tree node x, int r)
{
if x is a leaf return r
else
return rank(x->left_child, r + 1)+ ranks(x->right_child, r + 1) + r
}
rank(tree->root, 0)
答案 1 :(得分:1)
它可以在二叉树中O(n)
的{{1}}时间内解决
它只是根节点高度为零的所有节点的高度之和。
作为
算法:
输入左右子的二进制树
总和= 0;
输出总和
n is number of Nodes
修改强>
这也可以使用遍历树的队列或级别顺序来解决
使用队列的算法:
PrintSumOfrank(root,sum):
if(root==NULL) return 0;
return PrintSumOfrank(root->lchild,sum+1)+PrintSumOfRank(root->Rchild,sum+1)+sum;
答案 2 :(得分:1)
你是对的但是有一个 O(n) 解决方案,你可以使用更多的"复杂的"数据结构。 每当你添加/删除时,让每个节点保持其排名并更新排名,这样你就可以使用O(1)语句:
return 1 + node->left.rank + node->right.rank;
并对树上的每个节点执行此操作以实现 O(n) 。
缩短复杂性时间的缩略规则是:如果您可以复杂数据结构并添加功能以使其适应您的问题,则可以将复杂性时间缩短为 O(n) < / strong>大部分时间。