除此之外,您可能还有一个逻辑错误,但是,因为 C [我假设] 是按值调用的,所以设置 res 和 i 在给定函数调用的本地更改,但随后被丢弃。您需要传递一些地址,如下所示。特别要注意的是,res 现在在 postTrav 中是 TreeNode **。
TreeNode *
lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q)
{
TreeNode *res = NULL;
int i = 0;
postTrav(root, p, q, &res, &i);
return res;
}
void
postTrav(TreeNode *root, TreeNode *p, TreeNode *q, TreeNode **res, int *i)
{
if (!root) {
return;
}
postTrav(root->left, p, q, res, i);
postTrav(root->right, p, q, res, i);
if (root == p || root == q) {
*i++;
}
if (*i == 2) {
*res = root;
*i++;
}
}
更新:
上面的代码很好。但是,每当我有一个函数需要[并行地]返回或维护两个或多个值时,我使用的一种技术是创建一个额外的“遍历”或“帮助”结构,以简化参数传递。
如果您需要在调用中修改/维护一个额外的变量,而不是向所有函数添加一个额外的参数,只需向结构添加另一个变量就变得容易/容易了。这在您构建逻辑时特别有效。
这是优化的代码。请注意,需要推送/弹出的参数更少。而且,这可能比原来的执行速度更快或更快。另外,对我来说,trav->res 似乎比*res 干净一些
// traversal "helper" struct
struct _traverse {
TreeNode *p; // not modified
TreeNode *q; // not modified
TreeNode *res; // result
int i; // depth
// add more variables here as desired ...
#ifdef WANT_TRAVERSAL_STATISTICS
int visited_count; // number of nodes we visited
#endif
};
typedef struct _traverse Traverse;
TreeNode *
lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q)
{
Traverse trav;
trav.p = p;
trav.q = q;
trav.res = NULL;
trav.i = 0;
#ifdef WANT_TRAVERSAL_STATISTICS
trav.visited_count = 0;
#endif
postTrav(root, &trav);
#ifdef WANT_TRAVERSAL_STATISTICS
printf("Visited %d Nodes\n",trav.visited_count);
#endif
return trav.res;
}
void
postTrav(TreeNode *root, Traverse *trav)
{
if (!root) {
return;
}
#ifdef WANT_TRAVERSAL_STATISTICS
trav->visited_count += 1;
#endif
postTrav(root->left, trav);
postTrav(root->right, trav);
if (root == trav->p || root == trav->q) {
trav->i++;
}
if (trav->i == 2) {
trav->res = root;
trav->i++;
}
}