如何在没有C语言的全局变量的情况下递归返回指针?

发布于 2025-02-10 07:42:37 字数 366 浏览 2 评论 0原文

struct tree {
   char info;
   struct tree* left;
   struct tree* right;
};

typedef struct tree Tree;

Tree* address = NULL; // How to remove this global variable?

void nodeAddress (Tree* a, char v) {
   if (a != NULL) {
      nodeAddress(a->left, v);
      if (a->info == v) address = a;
      nodeAddress(a->right, v);   
   }
}
struct tree {
   char info;
   struct tree* left;
   struct tree* right;
};

typedef struct tree Tree;

Tree* address = NULL; // How to remove this global variable?

void nodeAddress (Tree* a, char v) {
   if (a != NULL) {
      nodeAddress(a->left, v);
      if (a->info == v) address = a;
      nodeAddress(a->right, v);   
   }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

悲喜皆因你 2025-02-17 07:42:37

只需使用返回,除非您真的认为双分球更清晰。

由于您已经指定了目标,因此很难为您提供一个很好的例子:

  • 如果多个节点可以匹配v,那么您的代码将选择最正确的一个,但是< /p>

  • 如果我们只能假设一个节点可以匹配v,或任何匹配的节点都是一个很好的结果,然后您可以优化一些不必要的递归(除非您知道 您可以通过在整个树上递归递归来保护Fe Fe Fe Ater Assing side schannel攻击案例)。

因此,以下是一个更简单的示例,假设第一个匹配项很好:

struct tree {
   char info;
   struct tree * left;
   struct tree * right;
};

struct tree * find_matching_node(struct tree * a, char v)
{
   struct tree * found = NULL;
   if (a != NULL)
   {
       if (a->info == v)
       {
           found = a;
       }
       if(found == NULL)
       {
           found = find_matching_node(a->left, v);
       }
       if(found == NULL)
       {
           found = find_matching_node(a->right, v);
       }
   }
   return found;
}

但是,这完全等同于您的示例:

struct tree * find_matching_node(struct tree * a, char v)
{
   struct tree * found = NULL;
   struct tree * found_rightmost;
   if (a != NULL)
   {
       if (a->info == v)
       {
           found = a;
       }
       if(found == NULL)
       {
           found = find_matching_node(a->left, v);
       }
       found_rightmost = find_matching_node(a->right, v);
       if(found_rightmost != NULL)
       {
           return found_rightmost;
       }
   }
   return found;
}

您当然可以执行双指针,这是一个较小的代码更改:

void find_matching_node(struct tree * a, char v, struct tree * * found)
{
   if (a != NULL) {
      find_matching_node(a->left, v, found);
      if (a->info == v) *found = a;
      find_matching_node(a->right, v, found);   
   }
}

但是请注意,最后一个版本都保留了同时效率低下的效率。递归到整棵树上,以及如果有多种匹配,则含义哪种行为。效率低下可以通过强大的优化编译器来解决,但是歧义将代码锁定在右半部分中,以防万一您打算 houts 以在多个发生多个的情况下获得正确的匹配比赛。

Just use return, unless you really think the double-pointer is clearer.

Since you've underspecified your goal, it is hard to give you a good example:

  • if more than one node can match v, your code is will pick the right-most one, but

  • if we can assume only one node can match v, or any matching node is a good result, then you can optimize out some needless recursion (unless of course you know you're justifiably protecting against f.e. a timing side-channel attack by recursing over the whole tree in all cases).

So, here's the simpler example assuming the first match found is good:

struct tree {
   char info;
   struct tree * left;
   struct tree * right;
};

struct tree * find_matching_node(struct tree * a, char v)
{
   struct tree * found = NULL;
   if (a != NULL)
   {
       if (a->info == v)
       {
           found = a;
       }
       if(found == NULL)
       {
           found = find_matching_node(a->left, v);
       }
       if(found == NULL)
       {
           found = find_matching_node(a->right, v);
       }
   }
   return found;
}

But here's one that's exactly equivalent to your example:

struct tree * find_matching_node(struct tree * a, char v)
{
   struct tree * found = NULL;
   struct tree * found_rightmost;
   if (a != NULL)
   {
       if (a->info == v)
       {
           found = a;
       }
       if(found == NULL)
       {
           found = find_matching_node(a->left, v);
       }
       found_rightmost = find_matching_node(a->right, v);
       if(found_rightmost != NULL)
       {
           return found_rightmost;
       }
   }
   return found;
}

You can of course do the double pointer, which is a smaller code change:

void find_matching_node(struct tree * a, char v, struct tree * * found)
{
   if (a != NULL) {
      find_matching_node(a->left, v, found);
      if (a->info == v) *found = a;
      find_matching_node(a->right, v, found);   
   }
}

But notice that this last version retains both the inefficiency of recursing into the whole tree and the ambiguity about which behavior is intended if there are multiple matches. The inefficiency can be solved by a strong-enough optimizing compiler, but the ambiguity locks the code into always recursing into the right half just in case you intended to get the right-most match in the event of multiple matches.

み青杉依旧 2025-02-17 07:42:37

我同意以上的观点,您应该只需使用返回

还考虑将另一层抽象用于指针,这完全是个人选择的问题。我个人发现这种类型的指针类型定义使代码更加干净:

struct tree;
typedef struct tree *Position;
typedef struct tree
{
   char info;
   Position left;
   Position right;
} Tree; 

I agree with the above, you should just simply use return.

Consider also the use of another layer of abstraction for pointers, which is completely a matter of personal choice. I personally find this type of pointer type definition makes the code a lot cleaner:

struct tree;
typedef struct tree *Position;
typedef struct tree
{
   char info;
   Position left;
   Position right;
} Tree; 
我是有多爱你 2025-02-17 07:42:37

遵循您的提示,我找到了解决方案。谢谢!这是代码:

find_matching_node(tree* a,char v,tree **找到){

if(a!= null){

  find_matching_node(a->left, v, found);

  if (a->info == v) *found = a;

  find_matching_node(a->right, v, found);

}

}

tree* find(tree* a,char v){

树*

if(a!= null){

  if (a->info == v) {

     found = a;

     return found;

  }

  if(found == NULL) find_matching_node(a->left, v, &found);

  if(found == NULL) find_matching_node(a->right, v, &found);

}

返回找到;

}

void main(){

tree* x = find(root,'a');

}

Following your tips, I found the solution. Thanks! Here's the code:

find_matching_node(Tree* a, char v, Tree** found) {

if (a != NULL) {

  find_matching_node(a->left, v, found);

  if (a->info == v) *found = a;

  find_matching_node(a->right, v, found);

}

}

Tree* find(Tree* a, char v) {

Tree* found = NULL;

if (a != NULL) {

  if (a->info == v) {

     found = a;

     return found;

  }

  if(found == NULL) find_matching_node(a->left, v, &found);

  if(found == NULL) find_matching_node(a->right, v, &found);

}

return found;

}

void main() {

Tree* x = find(root, 'a');

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文