【问题标题】:trying to understand this recursion试图理解这种递归
【发布时间】:2021-05-15 00:25:43
【问题描述】:

我需要取一个链表并返回它的镜像版本,这里是一个例子

输入:1->2->3->4->5->null。

结果:1​​->2->3->4->5->5->4->3->2->1->NULL。

每个节点只需要访问一次

我设法解决了它,但我真的无法理解解决方案,所以任何人都可以帮助我分解镜像功能吗?

我的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    int data;
    struct node* next;

} node;


void PushEnd(node** headRef, int data)

{
    node* newnode = malloc(sizeof(node));

    if (!newnode)
        return;

    newnode->data = data;

    if (*headRef == NULL)
        {
            newnode->next = NULL;
            *headRef = newnode;
        }
    else
        {
            node* current = *headRef;
            node* prev;
            while (current->next)
                {
                    current = current->next;
                }
            current->next = newnode;
            newnode->next = NULL;
        }
}


void printList(node* head)
{
    if (head == NULL)
        return;
    printf("%d ", head->data);

    printList(head->next);
}
node* mirror(node* head)
{
    node* new = NULL;
     
    if (head == NULL)
        return NULL;
    
    PushEnd(&new,head->data);
    
    new->next=mirror(head->next);
   PushEnd(&new, head->data); 
    return new;
}
void Test()
{
    node* head = NULL;
    
    int a[] = {10,50,19,54,30};
    for (int i = 0; i < (sizeof(a) / sizeof(int)); i++)
        {
            PushEnd(&head, a[i]);
            
        }
    printList(head);
    printf("\n");
    node* new = mirror(head);
    printList(new);
}
int main()
{
    Test();
    return 0;
}

使用这个调用:new->next=mirror(head->next); 它是如何推送第一个元素的?

提前致谢

【问题讨论】:

  • 如果你设法解决了问题,并且确定你已经解决了,但你不明白为什么,那么我知道很多公司会对你的资料感兴趣。一般来说,软件项目都充满了没人理解的问题:-)
  • 即使我认识太多这样的开发人员......你怎么能假装已经解决了它(你自己)并且你不知道它是如何工作的? “解决”是“复制随机找到的东西,哇,神奇地起作用”的新词吗? -- 无论如何,在您的代码中插入大量printf() 调用以遵循控制流并观察相关值。这是使用调试器的简单替代方法。

标签: c recursion linked-list singly-linked-list function-definition


【解决方案1】:

在函数的第一次调用中,指针new 等于NULL。然后调用函数PushEnd

PushEnd(&new,head->data);

所以现在结果列表看起来像(如果要使用数组中的数据)

| 10 | NULL |
     ^
     |
    new

然后函数递归调用自身(例如对于值为50的数组元素)

new->next=mirror(head->next);

退出此调用后,由于在上面的语句中分配给指针 new->next,您将拥有

| 10 | ->50 | -> | 50 | ...| -> ... | ...| NULL|
     ^
     |
    new

现在将值 10 附加到列表的尾部

PushEnd(&new, head->data);

你将拥有

| 10 | ->50 | -> | 50 | ...| -> ... | ...| ->10 | -> | 10 | NULL |
     ^
     |
    new

由于调用了函数PushEnd,这种方法效率低下,因为它需要遍历整个新构建的列表才能实现它的尾部。

【讨论】:

  • 抱歉回来晚了。我的导师说镜像函数多次遍历原始链表,请您详细说明,谢谢btw!
猜你喜欢
  • 2012-11-08
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 2015-03-23
  • 2016-11-15
相关资源
最近更新 更多