【问题标题】:Returning a value in recursion递归返回一个值
【发布时间】:2021-07-21 19:55:10
【问题描述】:

我是 stackoverflow 的新手,因此请随时根据需要更改或编辑我的问题。

我正在尝试修复以下代码,它本质上只是一个中序树遍历:

void *inorder_traversal(void *heapstart, uint32_t size, void *address) {
    struct node *head = (struct node* )heapstart;
    if (head->left_child == NULL) {
        if (condition1) {
            if (condition2) {
                address = head->address;
            }
        }
    } else {
        inorder_traversal(head->left_child, size, address);
        inorder_traversal(head->right_child, size, address);
    }
    return address;
}

我目前正在尝试返回一个void *,该void * 存储在我正在经历的一个节点中。该节点必须满足条件1(size < pow(2, head->initial_size) && size > pow(2, (head->initial_size) - 1))和条件2head->current_state == free。为了便于阅读,我已从代码中删除了这些内容。

当我尝试提取地址并将其返回时,我的问题出现了。我有那个address = head->address。但是,因为每当递归发生时head 都会发生变化,所以head->address 总是指向满足我条件的最后一个节点head->address 而不是head->address

基本上我在问是否有办法在满足条件时中断遍历并返回我存储的地址。

有人建议我没有返回正确的值,但我不确定这是什么意思。

如果有任何混淆,请告诉我。

【问题讨论】:

  • head->left_child == NULL检查的目的是什么?
  • 我只对叶节点感兴趣,我生成树的方式是我总是同时拥有left_childright_child,并且它们在初始化时将是NULL。因此,检查是否有 left_child 足以让我验证它的叶子节点。
  • 那些递归潜水仍然返回一些东西,你知道的。也许您应该保留它,而不是仅仅将其设置为忽略它。我还看到在这个函数中传递address 是零点。您仅将它用作赋值目标,并且作为值参数,它最终毫无价值,因为一旦函数返回,收获就会丢失。
  • 您是否正在寻找满足这些条件的第一个有序节点?
  • @WhozCraig 是的,我同意,没有理由传递地址,这只是我尝试过的旧解决方案遗留下来的东西。我试图让 void* address; 在我的主目录中未初始化。然后将它传递给这个函数,而不是返回void*,而是返回void,在这个函数中初始化它之后,我会在我的main中访问它。

标签: c pointers recursion


【解决方案1】:

我猜这个问题可能是由于使用了类似于局部变量的函数参数address。因此,address 的修改在其他递归调用的上下文中是不可见的。

我建议不要使用这个参数。只要找到第一个满足条件的节点就返回结果。

void *inorder_traversal(void *heapstart, uint32_t size)) {
    struct node *head = (struct node* )heapstart;
    if (head->left_child == NULL) {
        if (condition1) {
            if (condition2) {
                return head->address;
            }
        }
        // this branch is empty
        return NULL;
    }
    // try left child, if it fails then try the right one
    void *address = inorder_traversal(head->left_child, size);
    if (address) return address;
    return inorder_traversal(head->right_child, size);
}

【讨论】:

  • 谢谢你的建议,我看看我能不能让它工作。
  • 这个带有一些调整的解决方案是我让它工作所需的一切。事后看来很有道理。谢谢你!
【解决方案2】:

按顺序遍历应该(递归地)按以下顺序访问节点:节点的左子树、节点本身、节点的右子树。

如果没有节点满足条件,不清楚 OP 的 inorder_traversal 函数应该返回什么,所以我假设它应该返回 NULL

我在下面的inorder_traversal 函数版本中省略了address 参数,因为它没有被使用。

void *inorder_traversal(void *heapstart, uint32_t size)
{
    struct node *head = heapstart;
    void *address;

    /* Deal with empty sub-tree. */
    if (head == NULL) {
        return NULL;
    }
    /* Check the left sub-tree for a suitable address. */
    address = inorder_traversal(head->left_child, size);
    if (address == NULL) {
        /* Check the head for a suitable address. */
        if (condition1) {
            if (condition2) {
                address = head->address;
            }
        }
    }
    if (address == NULL) {
        /* Check the right sub-tree for a suitable address. */
        address = inorder_traversal(head->right_child, size);
    }
    return address;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2021-01-06
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    相关资源
    最近更新 更多