递归返回值

时间:2021-04-28 12:49:55

标签: c pointers recursion

我是 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 *。此节点必须满足条件 1 (size < pow(2, head->initial_size) && size > pow(2, (head->initial_size) - 1)) 和条件 2 head->current_state == free。为了便于阅读,我已从代码中删除了这些内容。

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

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

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

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

2 个答案:

答案 0 :(得分:2)

我猜这个问题可能是由于使用了一个行为类似于局部变量的函数参数 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);
}

答案 1 :(得分:0)

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

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

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

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;
}