C++ 复制链接列表(C+;+;)

C++ 复制链接列表(C+;+;),c++,linked-list,singly-linked-list,C++,Linked List,Singly Linked List,我试图复制我的链表,当我调用cpyLl()时,它进入了无休止的循环;功能 我的预期产出是: 102030102030 我实际上使用函数来定义节点,但由于代码的复杂性,我现在正在用main编写它 我使用的是Dev-C++5.11。您的编译器应该会警告您以下文件中的未知类型n: struct n{//The definition of Linked List int x; struct n * next; }; typedef struct n node; int counter(

我试图复制我的链表,当我调用cpyLl()时,它进入了无休止的循环;功能

我的预期产出是:

102030102030

我实际上使用函数来定义节点,但由于代码的复杂性,我现在正在用main编写它


我使用的是Dev-C++5.11。

您的编译器应该会警告您以下文件中的未知类型
n

struct n{//The definition of Linked List
    int x;
    struct n * next;
};
typedef struct n node;

int counter(node *r){ //Counting the node.
    int y=0;
    while(r != NULL){
        y++;
        r = r->next;
    }
    return y;       
}

//The problem is down there

void cpyLl(node *r){    //Copying link list
    int temp;
    for (int y = counter(r); y > 0 ;y--){
        temp = r -> x;
        while (r -> next != NULL){
            r = r -> next;
        } 
        r -> next = (node *)malloc(sizeof(node));
        r = r->next;
        r -> x = temp;
    }
}

int main(){
    node * root;
    root = (node *)malloc(sizeof(node));
    root -> x = 10;
    root -> next = (node *)malloc(sizeof(node));
    root -> next -> x = 20;
    root -> next -> next =(node *)malloc(sizeof(node));
    root -> next -> next -> x =30;
    root -> next -> next -> next = NULL;
    cpyLl(root);
    return 0;
}
在您声明
n*next时,
n
的类型未知。要解决此问题,您需要在
n
之前包含
struct
,例如

struct n {  //The definition of Linked List
    int x;
    n * next;
};
struct n {  //The definition of Linked List
    int x;
    struct n * next;
};
您的
typedef
中也存在此问题,例如:

struct n {  //The definition of Linked List
    int x;
    n * next;
};
struct n {  //The definition of Linked List
    int x;
    struct n * next;
};
此时,
n
也是未知的。相反,你需要

typedef n node;
正如bruno指出的,当未初始化时,您在
计数器中使用
x
调用未定义的行为,例如:

typedef struct n node;
初始化
int x=0
以进行补救

副本列表问题

首先,不要在
r=r->next中的
->
周围放置空格箭头操作符应直接连接结构和成员

您的
cpyLl()
函数不会复制任何内容。为了复制列表,您需要函数返回指向新复制列表的指针。例如,这样做是有意义的:

int counter(node *r){ //Counting the node.

    int x;
    while(r != NULL){
        x++;             /* what is the value of x on the first iteration? */
        ...
在您的功能中,您需要分配/创建一个新的第一个节点,并为副本分配第一个数据值,然后对在所有节点上循环的其余节点基本上重复此操作,为复制和复制值创建一个新分配的节点。您需要保留指向复制列表开头的指针才能返回。在
cpyL1
中根本不需要
计数器。如果有一个链表,可以使用
next
指针在该列表上迭代。e、 g

/* cpyL1 should return a pointer to the head of the newly copied list */
node *cpyLl (node *r) {
注意:您必须验证每个分配。)

现在,如果您只想复制一个特定的节点,那么您可以迭代,直到找到值或地址,然后只复制一个节点

将其放在一起,并添加打印列表和免费列表功能,您可以执行类似的操作:

/* cpyL1 should return a pointer to the head of the newly copied list */
node *cpyLl (node *r) {

    node *copy = NULL, *p;  /* pointers for new list - initialized NULL */

    if (!r) {   /* validate r is not NULL */
        fputs ("error: list to copy is empty.\n", stderr);
        return NULL;
    }

    copy = malloc (sizeof *copy);   /* allocate 1st node of copy */
    if (!copy) {
        perror ("malloc-copy");
        return NULL;
    }
    p = copy;
    p->x = r->x;

    while (r->next) { /* copy all nodes from r to copy */
        p->next = malloc (sizeof *p->next); /* allocate each node */
        if (!p->next) {     /* validate the allocation */
            perror ("malloc-p->next");
            return copy;    /* return partial copy of list */
        }
        r = r->next;        /* advance to next node */
        p = p->next;

        p->x = r->x;        /* set node value */
        p->next = NULL;
    }

    return copy;    /* return pointer to newly copied list */
}
内存使用/错误检查

不要忘记验证内存使用是否存在任何错误

$ ./bin/structfwd

original list:

 10 20 30

copy of list:

 10 20 30
cpyLl()
中,您没有初始化分配的每个新
节点的
next
字段
malloc()
不会将分配的内存归零(如果需要,请改用
calloc()

此外,在进入
for
循环之前,确实应该移动
while
循环,该循环位于
for
循环中,用于查找列表中的最后一个节点。没有理由在每个
上使用
循环进行
循环迭代时,只需将新节点附加到分配的前一个节点上即可

请尝试类似以下内容:

$ valgrind ./bin/structfwd
==12148== Memcheck, a memory error detector
==12148== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==12148== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==12148== Command: ./bin/structfwd
==12148==

original list:

 10 20 30

copy of list:

 10 20 30
==12148==
==12148== HEAP SUMMARY:
==12148==     in use at exit: 0 bytes in 0 blocks
==12148==   total heap usage: 6 allocs, 6 frees, 96 bytes allocated
==12148==
==12148== All heap blocks were freed -- no leaks are possible
==12148==
==12148== For counts of detected and suppressed errors, rerun with: -v
==12148== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
struct节点{
int x;
节点*下一步;
};
int countLinkedList(节点*n,节点**last=NULL){
整数计数=0;
如果(last)*last=NULL;
while(n){
++计数;
如果(最后)*最后=n;
n=n->next;
}
返回计数;
}
节点*makeLinkedListNode(int x){
node*n=新节点;//(node*)malloc(sizeof(node));
n->x=x;
n->next=NULL;
返回n;
}
无效freeLinkedList(节点*n){
节点*下一步;
while(n){
next=n->next;
删除n;//空闲(n);
n=下一个;
}
}
void copyLinkedList(节点*n){
节点*最后;
for(int y=countLinkedList(n,&last);y>0;--y){
last->next=makeLinkedListNode(n->x);
最后一个=最后一个->下一个;
n=n->next;
}
}
无效printLinkedList(节点*n){
while(n){
std::cout x next;
}
std::cout next=makeLinkedListNode(20);
root->next->next=makeLinkedListNode(30);

std::cout in counter你没说x没有初始化(为0),我也没说cpyLl这么“奇怪”^^^谁知道呢
:)
也许这是个谜(祈祷吧…)使用
计数器中未初始化的
x
,for
循环会变得非常有趣。感谢您的帮助。很高兴提供帮助。祝您编码顺利,并始终初始化变量
:p
请解释cpyLl@bruno我真的这么做了。它旁边写着正在复制链接列表。你是在尝试吗o复制当前列表末尾的列表?@SefaKalkan我无法理解您的意思said@SefaKalkan是的,我不能理解。我编辑了你的代码,在cpyLl中有一个} Before copy: 10 20 30 After copy: 10 20 30 10 20 30
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>

void printLinkedList(const std::list<int> &l) {
    for(int x : l) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
}

int main() {
    std::list<int> l;
    l.push_back(10);
    l.push_back(20);
    l.push_back(30);

    std::cout << "Before copy: ";
    printLinkedList(l);

    std:copy_n(l.begin(), l.size(), std::back_inserter(l));

    std::cout << "After copy: ";
    printLinkedList(l);

    return 0;
}
Before copy: 10 20 30 After copy: 10 20 30 10 20 30