【问题标题】:Duplicating a linked list without using recursion不使用递归复制链表
【发布时间】:2022-11-12 12:47:04
【问题描述】:

我试图弄清楚如何复制一个链表,在对 Vs 代码进行调试后,我在cuurent->data = temp->data; 上遇到了分段错误 我不确定为什么会这样。

这是代码:

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

struct node {
    int data;
    struct node* next;
};
struct node* head;
struct node* head2;

struct node* Insert(struct node* head, int x)
{
    struct node* temp = (struct node*)malloc(sizeof(struct node));
    temp->data = x;
    temp->next = head;
    return temp;
}

void Print(struct node* head)
{
    struct node* tmp1 = head;
    printf("List is:");
    while (tmp1 != NULL) {
        printf(" %d", tmp1->data);
        tmp1 = tmp1->next;
    }
    printf("\n");
}

struct node* dupe(struct node* head, struct node* head2)
{
    if (head == NULL)
        return NULL;
    struct node* temp = head;
    struct node* prev = NULL;
    struct node* cuurent = (struct node*)malloc(sizeof(struct node));
    cuurent->data = temp->data;
    if (head2 == NULL) {
        cuurent->next = head2;
        head2 = cuurent;
    }
    while (temp != NULL) {
        temp = temp->next;
        cuurent = (struct node*)malloc(sizeof(struct node));
        cuurent->data = temp->data;
        cuurent->next = prev;
        prev = cuurent;
    }
    return head2;
}

int main(void)
{
    head = NULL;
    head2 = NULL;
    head = Insert(head, 4);
    head = Insert(head, 2);
    head = Insert(head, 3);
    head = Insert(head, 5);
    head2 = dupe(head, head2);
    Print(head);
    Print(head2);
}

【问题讨论】:

  • 您移动 temp = temp-&gt;next; 并且不再检查 tempcuurent-&gt;data = temp-&gt;data; 之前是否为空指针 - 您的逻辑在这里有缺陷
  • 没有检查您的代码,但可能是未初始化或 NULL 指针。如果您包含回溯,这会很有帮助,您甚至可以自己看到答案。此外,值得一提的是您的编译器和平台,以获得潜在的提示。
  • 我不明白head2 在这段代码中的作用是什么,无论是在main 还是在你的dupe 函数中。关于不递归复制链表,一个简单的前向链循环应该很简单,只需要大约 8 行函数代码。
  • 所以用递归来做这件事对你来说不是问题吗?
  • 我建议使用更多不同的标识符。编译器可能对全局变量和多个同名参数没有问题。但我不相信自己有那种狡猾的细节。

标签: c pointers linked-list


【解决方案1】:

正如 cmets 中指出的那样,

while (temp != NULL) {
    temp = temp->next;

立即更改temp 的值防止空指针值。

这最终意味着

cuurent->data = temp->data;

当它是空指针值时,将通过取消引用temp 来导致Undefined Behaviour


您可以应用Print 中显示的完全相同的循环原则来复制列表。唯一的区别是您必须保存指向第一个节点的指针。

当需要free内存时,可以再次使用相同的原理。

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

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

struct node *insert(struct node *next, int x)
{
    struct node *n = malloc(sizeof *n);

    n->data = x;
    n->next = next;

    return n;
}

void print_list(struct node *head)
{
    printf("List is: ");

    while (head) {
        printf("%d ", head->data);
        head = head->next;
    }

    printf("
");
}

void free_list(struct node *head)
{
    struct node *t;

    while (head) {
        t = head->next;
        free(head);
        head = t;
    }
}

struct node *copy_list(struct node *head)
{
    struct node *root = NULL;

    for (struct node *current; head; head = head->next) {
        struct node *new = insert(NULL, head->data);

        if (!root)
            root = new;
        else
            current->next = new;

        current = new;
    }

    return root;
}

int main(void)
{
    struct node *head = NULL;
    head = insert(head, 4);
    head = insert(head, 2);
    head = insert(head, 3);
    head = insert(head, 5);

    struct node *head2 = copy_list(head);

    print_list(head);
    print_list(head2);

    free_list(head);
    free_list(head2);
}

输出:

List is: 5 3 2 4 
List is: 5 3 2 4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 2020-07-22
    • 2013-03-28
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    相关资源
    最近更新 更多