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;
}
我试图复制我的链接列表,当我调用cpyLl()时,它进入了无限循环。功能。
我的预期输出是:
10 20 30 10 20 30
我实际上使用函数来定义节点,但是由于代码复杂,我现在主要在编写它。
我正在使用Dev-C ++ 5.11。
答案 0 :(得分:1)
您的编译器应警告您以下类型为n
的未知类型:
struct n { //The definition of Linked List
int x;
n * next;
};
在声明n
时,n * next;
的类型未知。为了解决这个问题,您需要在struct
之前加入n
,例如
struct n { //The definition of Linked List
int x;
struct n * next;
};
您的typedef
中也存在此问题,例如
typedef n node;
目前n
尚不清楚。相反,您需要。
typedef struct n node;
正如bruno指出的那样,您在未初始化的x
中使用counter
来调用未定义行为,例如:
int counter(node *r){ //Counting the node.
int x;
while(r != NULL){
x++; /* what is the value of x on the first iteration? */
...
初始化int x = 0
进行补救。
复制列表问题
首先不要在->
中的r = r->next;
周围放置空格。箭头运算符应直接连接结构和成员。
您的cpyLl()
函数不会复制任何内容。为了复制列表,您需要您的函数将指针返回到新复制的列表。例如,这样做很有意义:
/* cpyL1 should return a pointer to the head of the newly copied list */
node *cpyLl (node *r) {
在您的函数中,您需要分配/创建一个新的第一个节点并为副本分配第一个数据值,然后对其余节点进行实质上的重复,遍历所有节点,创建一个新分配的节点以进行复制并复制该值。您将需要保留一个指向复制列表开头的指针以返回。 counter
内完全不需要cpyL1
。您有一个链接列表,可以使用next
指针在列表上进行迭代。例如
/* 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 */
}
(注意:,您必须验证每个分配。)
现在,如果您只想复制一个特定的节点,则可以迭代直到找到值或地址,然后简单地复制一个节点。
将其全部放入并添加打印列表和自由列表功能,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
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;
}
/* 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 */
}
void prnlist (node *l)
{
while (l) {
printf (" %d", l->x);
l = l->next;
}
putchar ('\n');
}
void freelist (node *l)
{
while (l) {
node *victim = l;
l = l->next;
free (victim);
}
}
int main (void) {
node *root, *p, *copy = NULL;
root = malloc (sizeof *root);
/* first node */
if (!root) { /* validate EVERY allocation */
perror ("malloc-root");
return 1;
}
root->x = 10;
p = root; /* assign pointer to root */
/* second node */
p->next = malloc (sizeof *p->next);
if (!p->next) { /* validate EVERY allocation */
perror ("malloc-p->next");
return 1;
}
p = p->next;
p->x = 20;
/* third node */
p->next = malloc (sizeof *p->next);
if (!p->next) { /* validate EVERY allocation */
perror ("malloc-p->next");
return 1;
}
p = p->next;
p->x = 30;
p->next = NULL; /* set p->next to NULL */
copy = cpyLl(root); /* copy root list to copy */
if (!copy) {
fputs ("error: copy is NULL\n", stderr);
return 1;
}
puts ("\noriginal list:\n");
prnlist (root);
puts ("\ncopy of list:\n");
prnlist (copy);
freelist (root); /* don't forget to free what you allocate */
freelist (copy);
return 0;
}
使用/输出示例
$ ./bin/structfwd
original list:
10 20 30
copy of list:
10 20 30
内存使用/错误检查
不要忘记验证您的内存使用是否有任何错误。
$ 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)
答案 1 :(得分:1)
在cpyLl()
中,您没有初始化分配的每个新next
的{{1}}字段。 node
不会将分配的内存归零(如果需要,请使用malloc()
)。
此外,在进入calloc()
循环之前,实际上应该移动while
循环中的for
循环以查找列表中的最后一个节点。无需在每次for
循环迭代中使用while
循环,只需将新节点附加到您分配的上一个节点即可。
请尝试以下类似操作:
for
输出:
Before copy: 10 20 30 After copy: 10 20 30 10 20 30
话虽如此,实际上您应该使用标准的C ++容器和算法,例如:
struct node {
int x;
node *next;
};
int countLinkedList(node *n, node **last = NULL) {
int count = 0;
if (last) *last = NULL;
while (n) {
++count;
if (last) *last = n;
n = n->next;
}
return count;
}
node* makeLinkedListNode(int x) {
node *n = new node; // (node*) malloc(sizeof(node));
n->x = x;
n->next = NULL;
return n;
}
void freeLinkedList(node *n) {
node *next;
while (n) {
next = n->next;
delete n; // free(n);
n = next;
}
}
void copyLinkedList(node *n) {
node *last;
for (int y = countLinkedList(n, &last); y > 0; --y) {
last->next = makeLinkedListNode(n->x);
last = last->next;
n = n->next;
}
}
void printLinkedList(node *n) {
while (n) {
std::cout << n->x << " ";
n = n->next;
}
std::cout << std::endl;
}
int main() {
node *root = makeLinkedListNode(10);
root->next = makeLinkedListNode(20);
root->next->next = makeLinkedListNode(30);
std::cout << "Before copy: ";
printLinkedList(root);
copyLinkedList(root);
std::cout << "After copy: ";
printLinkedList(root);
freeLinkedList(root);
return 0;
}
输出:
Before copy: 10 20 30 After copy: 10 20 30 10 20 30