我想计算一棵二叉树中有多少个节点只有一个孩子。我不知道这是否可以。另外我也不知道是否必须使用树状搜索(例如postorder)。
size_t tree_one_child(const tree_t* t){
if(!t || number_children(t)==0){
return 0;
}
if(number_children(t)==1){
return 1 + tree_one_child(t->left) + tree_one_child(t->right);
}
else{
return tree_one_child(t->left) + tree_one_child(t->right);
}
size_t number_children(const tree_t* t){
int count = 0;
if(t->left != null ) count++;
if(t->right != null) count++;
return count;
}
答案 0 :(得分:0)
您对代码的一些评论:
您可以将if(!t || number_children(t)==0)
简化为if(!t)
。
为避免重复自己,您应将子代的递归计算保存在变量中:
size_t tree_one_child(const tree_t* t){
if(!t)
return 0;
size_t ret = tree_one_child(t->left) + tree_one_child(t->right);
if (number_children(t) == 1)
ret++;
return ret;
}
除非您在其他地方使用了number_children
,否则可以使用它:
size_t one_child(const tree_t* t){
return !t->left != !t->right;
}
表达式!a != !b
是执行逻辑异或的一种方法,这正是您想要的。它使代码更简洁。
size_t tree_one_child(const tree_t* t){
if(!t)
return 0;
size_t ret = tree_one_child(t->left) + tree_one_child(t->right);
if (one_child(t))
ret++;
return ret;
}
要使这段代码更短,您可以这样做:
size_t tree_one_child(const tree_t* t){
if(!t)
return 0;
return one_child(t) + tree_one_child(t->left) + tree_one_child(t->right);
}
有些人可能会认为这是不正确的做法,因为在布尔值之间加法(我知道one_child
从技术上返回size_t,但显然应该认为是对/错)实际上没有任何意义。它恰好起作用,因为它在true时返回1,在false时返回0。
您的代码会工作吗?
据我所知,它似乎可以完成任务,而且我看不到任何情况都会导致错误的结果或做任何不好的事情。
关于可以说服自己的建议是编写测试。我将为您提供快速指南。
首先,创建一个函数create_tree( .. )
,该函数根据其参数创建一棵树。也许您可以有一个仅使用char*
的函数,并对该字符串进行一些魔术处理以生成树。这样,您可以进行如下测试:
void test(char * s, int expected_output) {
tree_t * t = create_tree(s)
if(tree_one_child(t) == expected_output)
printf("Test passed\n");
else
printf(" TEST FAILED");
deallocate_tree(t);
}
test("1332", 3);
test("10423", 0);
注意,有相当标准化的方法可以执行此操作,但我想您会明白的。寻找一些方法来简化代码测试和测试。
答案 1 :(得分:-1)
好吧,您缺少函数tree_one_child()的右括号,但是除此之外,此代码仍然有效。
虽然有样式说明:通常,最好只有一个位置来完成特定的工作,例如计算您下方的单子节点数;您可以在两个地方进行操作。当然,当工作像recurse(left) + recurse(right)
一样简单时,它是非常安全的。但我会将此例程编写为
size_t tree_one_child(const tree_t* t) {
if (t == NULL)
return 0;
return number_children(t) + tree_one_child(t->left) + tree_one_child(t->right);
}
我认为这既安全(因为不可能有一天有人会修改某些节点的逻辑,而没有其他人修改逻辑)