克隆链接列表,我遇到了困难,我的代码中有什么问题?

发布于 2025-01-30 04:17:30 字数 1262 浏览 2 评论 0 原文

node 的结构:

class Node{
    public:
    int data;
    Node *next;
    Node *arb;
    Node(int value){
        data=value;
        next=NULL;
        arb=NULL;
    }
};

现在,我编写了以下代码,但是我会得到分割故障运行时错误。我找不到导致此错误的原因。

Node *copyList(Node *head)
    {
        Node* ptr=head;
        Node *temp;
        Node *clonehead; 
        Node *clonetail;
        while(ptr!=NULL){
            temp=ptr->next;
            Node* newnode=new Node(ptr->data);
            if(ptr==head){
                clonehead=newnode;
                clonetail=clonehead;
            }
            else{
                clonetail->next=newnode;
                clonetail=newnode;
            }
            clonetail->arb=ptr->arb;
            ptr->next=clonetail;
            ptr=temp;
        }
        ptr=clonehead;
        while(ptr!=NULL){
            temp=ptr->arb;
            ptr->arb=temp->next;
            ptr=ptr->next;
        }
        return clonehead;
    }

我的代码怎么了?

链接到问题:

Structure of Node:

class Node{
    public:
    int data;
    Node *next;
    Node *arb;
    Node(int value){
        data=value;
        next=NULL;
        arb=NULL;
    }
};

Now, I wrote the following code, but I am getting a segmentation fault runtime error. I can't find out what is causing this error.

Node *copyList(Node *head)
    {
        Node* ptr=head;
        Node *temp;
        Node *clonehead; 
        Node *clonetail;
        while(ptr!=NULL){
            temp=ptr->next;
            Node* newnode=new Node(ptr->data);
            if(ptr==head){
                clonehead=newnode;
                clonetail=clonehead;
            }
            else{
                clonetail->next=newnode;
                clonetail=newnode;
            }
            clonetail->arb=ptr->arb;
            ptr->next=clonetail;
            ptr=temp;
        }
        ptr=clonehead;
        while(ptr!=NULL){
            temp=ptr->arb;
            ptr->arb=temp->next;
            ptr=ptr->next;
        }
        return clonehead;
    }

What is wrong with my code?

Link to the problem: Clone a linked list with next and random pointer

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

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

发布评论

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

评论(1

╰ゝ天使的微笑 2025-02-06 04:17:30

您的代码中有几个错误:

  • clonetail-> arb = ptr-> arb;

    您提供的指令非常清楚, arb 克隆列表中的指示器需要指向克隆列表中的节点,而不是原始的节点列表。

  • ptr-> next = clonetail;

    您正在修改原始列表中节点的下一个指针,您根本不应该这样做。

  • 此代码完全没有意义:

      while(ptr!= null){
        temp = ptr-> arb;
        ptr-> arb = temp-> next;
        ptr = ptr-> next;
    }
     

    您正在通过克隆列表和每个 arb (指向原始列表中的一个节点,而不是克隆列表中的一个节点),而不是在克隆列表中),您将其更新为指向节点的下一个节点,而不是在引用节点本身上。您没有考虑到 arb 的可能性,或者克隆 arb s的事实指向错误列表中的节点。 P>

由于每个节点的 arb 都指向同一列表中的一个随机节点,因此您不能在克隆节点的同一循环中克隆 arb s arb 可能是指尚未克隆的后来节点。

要克隆 arb s,您必须先完成从原始列表中克隆节点,然后通过克隆的列表迭代其 arb s,以正确地指出克隆列表中的节点,而不是原始列表。我相信这是您尝试做的,但您没有正确地做。

话虽如此,请尝试更多类似的东西:

struct Node{
    int data;
    Node *next;
    Node *arb;

    Node(int value){
        data = value;
        next = NULL;
        arb = NULL;
    }
};

Node* resolveNode(Node *head, Node *clone, Node *target)
{
    while (head && clone){
        if (head == target)
            return clone;
        head = head->next;
        clone = clone->next;
    }
    return NULL;
}

Node* copyList(Node *head)
{
    Node *clonehead = NULL; 
    Node *ptr, **newnode = &clonehead;

    ptr = head;
    while (ptr != NULL){
        *newnode = new Node(ptr->data);
        newnode = &((*newnode)->next);
        ptr = ptr->next;
    }

    Node *cloneptr = clonehead;
    ptr = head;
    while (ptr != NULL){
        cloneptr->arb = resolveNode(head, clonehead, ptr->arb);
        cloneptr = cloneptr->next;
        ptr = ptr->next;
    }

    return clonehead;
}

或者,如果您可以省去一些额外的内存,则可以通过使用 std ::( Unordered_)映射来避免第二循环中重复的列表迭代以保持原始列表中哪些节点的曲目对应于克隆列表中的哪些节点,例如:

#include <map>

struct Node{
    int data;
    Node *next;
    Node *arb;

    Node(int value){
        data = value;
        next = NULL;
        arb = NULL;
    }
};

Node* copyList(Node *head)
{
    Node *clonehead = NULL; 
    Node *ptr, **newnode = &clonehead;
    std::map<Node*, Node*> node_lookup;

    ptr = head;
    while (ptr != NULL){
        *newnode = new Node(ptr->data);
        node_lookup.insert(std::make_pair(ptr, *newnode);
        newnode = &((*newnode)->next);
        ptr = ptr->next;
    }

    Node *cloneptr = clonehead;
    ptr = head;
    while (ptr != NULL){
        cloneptr->arb = node_lookup[ptr->arb];
        cloneptr = cloneptr->next;
        ptr = ptr->next;
    }

    return clonehead;
}

There are several mistakes in your code:

  • clonetail->arb=ptr->arb;

    The instructions you provided are very clear that the next and arb pointers in the cloned list need to point at nodes in the cloned list, not at nodes in the original list.

  • ptr->next=clonetail;

    You are modifying the next pointer of the nodes in the original list, which you should not be doing at all.

  • This code makes no sense at all:

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

    You are iterating through the cloned list, and for each arb (which is pointing at a node in the original list, not in the cloned list), you are updating it to point at the referred node's next node rather than at the referred node itself. You are not taking into account the possibility that arb may be NULL, or the fact that the cloned arbs are pointing at nodes in the wrong list to begin with.

Since each node's arb is pointing at a random node in the same list, you can't clone the arbs in the same loop that is cloning the nodes, as any given arb may be referring to a later node that hasn't been cloned yet.

To clone the arbs, you would have to first finish cloning the nodes from the original list, and then iterate through the cloned list updating its arbs to point at the correct nodes within the cloned list, not the original list. I believe this is what you are attempting to do, but you are not doing it correctly.

With that said, try something more like this:

struct Node{
    int data;
    Node *next;
    Node *arb;

    Node(int value){
        data = value;
        next = NULL;
        arb = NULL;
    }
};

Node* resolveNode(Node *head, Node *clone, Node *target)
{
    while (head && clone){
        if (head == target)
            return clone;
        head = head->next;
        clone = clone->next;
    }
    return NULL;
}

Node* copyList(Node *head)
{
    Node *clonehead = NULL; 
    Node *ptr, **newnode = &clonehead;

    ptr = head;
    while (ptr != NULL){
        *newnode = new Node(ptr->data);
        newnode = &((*newnode)->next);
        ptr = ptr->next;
    }

    Node *cloneptr = clonehead;
    ptr = head;
    while (ptr != NULL){
        cloneptr->arb = resolveNode(head, clonehead, ptr->arb);
        cloneptr = cloneptr->next;
        ptr = ptr->next;
    }

    return clonehead;
}

Alternatively, if you can spare some extra memory, you can avoid the repeated list iterations in the 2nd loop by using a std::(unordered_)map to keep track of which nodes in the original list correspond to which nodes in the cloned list, eg:

#include <map>

struct Node{
    int data;
    Node *next;
    Node *arb;

    Node(int value){
        data = value;
        next = NULL;
        arb = NULL;
    }
};

Node* copyList(Node *head)
{
    Node *clonehead = NULL; 
    Node *ptr, **newnode = &clonehead;
    std::map<Node*, Node*> node_lookup;

    ptr = head;
    while (ptr != NULL){
        *newnode = new Node(ptr->data);
        node_lookup.insert(std::make_pair(ptr, *newnode);
        newnode = &((*newnode)->next);
        ptr = ptr->next;
    }

    Node *cloneptr = clonehead;
    ptr = head;
    while (ptr != NULL){
        cloneptr->arb = node_lookup[ptr->arb];
        cloneptr = cloneptr->next;
        ptr = ptr->next;
    }

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