链表递归..为什么需要return语句?

发布于 2024-10-26 13:58:37 字数 750 浏览 1 评论 0原文

void add(llist *list, lnode *newNode){
    list->size++;
    addRecursion(&list->head, newNode);
}

lnode* addRecursion(lnode **node, lnode *newNode){
    if(*node == NULL){
        *node = newNode;
    }
    else{
        lnode *nextNode = (*node)->next;
        (*node)->next = addRecursion(&nextNode, newNode);

    }
    return *node;
}

这段代码工作正常..我在网上查看了代码并做了一些更改。但我仍然不明白为什么 addRecursion 函数必须有返回类型。我改变了功能,

void addRecursion(lnode **node, lnode *newNode){
        if(*node == NULL){
            *node = newNode;
        }
        else{
            lnode *nextNode = (*node)->next;
            addRecursion(&nextNode, newNode);

        }
    }

然后它不起作用..

void add(llist *list, lnode *newNode){
    list->size++;
    addRecursion(&list->head, newNode);
}

lnode* addRecursion(lnode **node, lnode *newNode){
    if(*node == NULL){
        *node = newNode;
    }
    else{
        lnode *nextNode = (*node)->next;
        (*node)->next = addRecursion(&nextNode, newNode);

    }
    return *node;
}

This code works fine.. I took a look at the codes online and made a few changes. But I still don't understand that why addRecursion function has to have the return type. I changed the function like

void addRecursion(lnode **node, lnode *newNode){
        if(*node == NULL){
            *node = newNode;
        }
        else{
            lnode *nextNode = (*node)->next;
            addRecursion(&nextNode, newNode);

        }
    }

then it didn't work..

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

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

发布评论

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

评论(5

若言繁花未落 2024-11-02 13:58:37

它总是返回存储到 *node 中的值,并且在修改后的代码中它会丢失该值,因为递归调用传递本地临时值而不是实际需要放置该值的位置,然后在返回后进行存储。一个非常奇怪的结构。如果您只是删除该本地变量,则可以使 addRecursion 无效(并且更简单):

void addRecursion(lnode **node, lnode *newNode){
    if(*node == NULL){
        *node = newNode;
    }else{
        addRecursion(&(*node)->next, newNode);
    }
}

It always returns the value it stores into *node, and in your modified code it loses that value since the recursive call passes a local temp rather than the place it actually needs to put the value, and then does the store after it returns. A very odd construct. You can make addRecursion void (and simpler) if you just get rid of that local var:

void addRecursion(lnode **node, lnode *newNode){
    if(*node == NULL){
        *node = newNode;
    }else{
        addRecursion(&(*node)->next, newNode);
    }
}
平生欢 2024-11-02 13:58:37

将某些内容分配给 (*node)->next。我想,它指向列表的下一个节点。因此,如果没有该分配,列表不会转到要添加新节点的最后一个节点。递归可以用迭代代替。

To assign something to (*node)->next. That points to the next node of the list, I suppose. So without that assignment, the list does not go to the last node, to which the new node is to be added. Recursion could be replaced with iteration.

稚然 2024-11-02 13:58:37

因为该函数返回下一个节点的地址,这是算法中设置最终节点所需的。

Because the function is returning the address of the next node which is required in your algorithm to set the final node.

只怪假的太真实 2024-11-02 13:58:37

随着递归的进行,它可能有助于可视化调用堆栈的增长/收缩。假设如下列表:

node1 -> node2 -> node3 -> null

然后 addRecursion 展开如下(伪代码):

addRecursion(&node1, newNode)
    node1.next = addRecursion(&node2, newNode);
        node2.next = addRecursion(&node3, newNode);
            node3.next = addRecursion(null, newNode); // returns &newNode
            node3.next = &newNode;
        node2.next = &node3;
    node1.next = &node2;
// return value ignored

新节点被添加到末尾,并且链中的每个链接都被保留。

It might help to visualize the call stack growing/shrinking as the recursion progresses. Assume the following list:

node1 -> node2 -> node3 -> null

Then addRecursion unfolds as follows (psuedocode):

addRecursion(&node1, newNode)
    node1.next = addRecursion(&node2, newNode);
        node2.next = addRecursion(&node3, newNode);
            node3.next = addRecursion(null, newNode); // returns &newNode
            node3.next = &newNode;
        node2.next = &node3;
    node1.next = &node2;
// return value ignored

The new node is added to the end and each link in the chain is preserved.

想挽留 2024-11-02 13:58:37

如果您对代码进行此调整,将 nextNode 的值重新分配回 (*node)->next ,因为您传递了该值,它也应该有效参考递归函数调用(因此在后来的递归调用期间对其进行了修改):

void addRecursion(lnode **node, lnode *newNode)
{
    if(*node == NULL)
    {
        *node = newNode;
        return;
    }

    lnode *nextNode = (*node)->next;
    addRecursion(&nextNode, newNode);
    (*node)->next = nextNode; //Add this line to re-connect the link
}

克里斯上面的版本更干净一些,因为它取消了两个赋值,并且这样做还节省了堆栈上的一些空间,因为没有存储本地指针变量 nextNode 所必需的。

It should also work if you make this adjustment to your code where you re-assign the value of nextNode back to (*node)->next since you passed that value by reference to the recursive function call (and therefore it was modified during the later recursive calls):

void addRecursion(lnode **node, lnode *newNode)
{
    if(*node == NULL)
    {
        *node = newNode;
        return;
    }

    lnode *nextNode = (*node)->next;
    addRecursion(&nextNode, newNode);
    (*node)->next = nextNode; //Add this line to re-connect the link
}

Chris's version above is a bit cleaner though since it axes out two assignments and in doing so also saves some space on the stack since there is no storage required for the local pointer variable nextNode.

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