使用此特定函数将元素附加到循环链表的末尾
Append an element to the end of a Circular Linked List with this particular function
我会尽量说清楚。
我在名为 "esercizio.h":
的文件中有这个结构(由于我的老师,我无法更改它)
#ifndef ESERCIZIO_H
#define ESERCIZIO_H
struct ElemSCL{
int info;
struct ElemSCL* next;
};
typedef struct ElemSCL NodoSCL;
typedef NodoSCL* TipoSCL;
void accoda(TipoSCL* pscl, int i);
#endif
函数"accoda"必须在循环链表(由TipoSCL* pscl 指向)的末尾添加一个元素(int i)。我试图将函数体写在一个名为 "esercizio.c":
的文件中
#include <stdio.h>
#include <stdlib.h>
#include "esercizio.h"
void accoda(TipoSCL* pscl, int i){
NodoSCL* temp = (NodoSCL*) malloc(sizeof(NodoSCL));
temp->info = i;
temp->next = temp;
if (pscl == NULL){
return;}
while ((*pscl)->next != *pscl){
*pscl = (*pscl)->next;}
(*temp)->next = (*pscl)->next; //Problems starts here
(*pscl)->next = *temp;
}
正如我在我的代码中让您注意到的那样,如果我不添加最后两行,一切正常。如果函数中没有 TypeSCL* 而是 NodeSCL* 我会使用:
temp->next = pscl->next;
pscl->next = temp;}
但是我的老师决定使用 TypeSCL* pscl 而不是 NodeSCL* pscl。
我有一个 "test.h" 文件...
#include "esercizio.h"
#ifndef TEST_H
#define TEST_H
char* toString(TipoSCL scl);
#endif
...和一个 "test.c" 文件,带有 main() 函数和所有让我检查我的代码是否正常工作的输入:
#include <stdlib.h>
#include <string.h>
#include "../libtest/libtest.h"
#include "test.h"
#include "esercizio.h"
const int NTEST=5;
TipoSCL input[5];
int add[5] = {1,2,3,4,5};
TipoSCL expected[5];
int main(int argc, char** argv){
input[0] = NULL;
input[1] = (TipoSCL) malloc(sizeof(NodoSCL));
input[1] -> info = 1;
input[1] -> next = input[1];
input[2] = (TipoSCL) malloc(sizeof(NodoSCL));
input[2] -> info = 1;
input[2] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[2] -> next -> info = 2;
input[2] -> next -> next = input[2];
input[3] = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> info = 1;
input[3] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> next -> info = 2;
input[3] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> next -> next -> info = 3;
input[3] -> next -> next -> next = input[3];
input[4] = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> info = 1;
input[4] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> info = 2;
input[4] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> next -> info = 3;
input[4] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> next -> next -> info = 4;
input[4] -> next -> next -> next -> next = input[4];
expected[0] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[0] -> info = 1;
expected[0] -> next = expected[0];
expected[1] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[1] -> info = 1;
expected[1] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[1] -> next -> info = 2;
expected[1] -> next -> next = expected[1];
expected[2] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> info = 1;
expected[2] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> next -> info = 2;
expected[2] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> next -> next -> info = 3;
expected[2] -> next -> next -> next = expected[2];
expected[3] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> info = 1;
expected[3] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> info = 2;
expected[3] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> next -> info = 3;
expected[3] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> next -> next -> info = 4;
expected[3] -> next -> next -> next -> next = expected[3];
expected[4] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> info = 1;
expected[4] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> info = 2;
expected[4] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> info = 3;
expected[4] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> next -> info = 4;
expected[4] -> next -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> next -> next -> info = 5;
expected[4] -> next -> next -> next -> next -> next = expected[4];
test_reset();
for (int i = 0; i < NTEST; i++) {
print_test_start(i+1);
printf("Funzione: accoda\n");
printf("Input: %s\n", toString(input[i]));
accoda(&input[i],add[i]);
test_compare_strings(toString(expected[i]),toString(input[i]));
print_test_end();
print_n_success("#Test superati: ");
}
print_test_result("Percentuale test corretti:");
}
char* toString(TipoSCL scl){
char* res = (char*) malloc(200*sizeof(char));
res[0] = '[';
res[1] = '[=14=]';
TipoSCL aux = scl;
if (aux != NULL) {
char buf[10];
do{
sprintf(buf,"%d->",aux -> info);
strcat(res,buf);
aux = aux -> next;
}
while(aux != scl);
sprintf(buf,"|%d",aux -> info);
strcat(res,buf);
aux = aux -> next;
}
strcat(res,"]");
return res;
}
我的代码 "everything is ok if I don't add the lasts two rows" 是什么意思?
当我 运行 我的程序(感谢终端和 cd 和 make )没有
(*temp)->next = (*pscl)->next; //Problems starts here
(*pscl)->next = *temp;
测试 运行 没有问题(当然,它说我没有一个正确的结果。但是如果我将这两行添加到我的代码中,我得到 "Segmentation fault: 11"。
我认为你的 pscl 指针必须到达链表的末尾,然后它应该插入临时元素。
你能做的是
void add(TypeSCL* pscl, int i){
NodeSCL* temp = (NodeSCL*) malloc(sizeof(NodeSCL));
temp->info = i;
temp->next = temp;
if (pscl == NULL){
return;
while(pscl->next != pscl)
pscl = pscl->next;
temp->next = (*pscl)->next; //THINGS GO WRONG HERE...
(*pscl)->next = temp; //...AND HERE
}
'
尝试将您的添加函数更改为此 ::
void add(TypeSCL* pscl, int i){
NodeSCL* temp = (NodeSCL*) malloc(sizeof(NodeSCL));
temp->info = i;
temp->next = temp;
if (*pscl == NULL){
*pscl = temp;
return;}
NodeSCL *tempCheck = *pscl;
while(tempCheck->next != *pscl) {
tempCheck = tempCheck->next;
}
tempCheck->next = temp;
temp->next = (*pscl);
}
你做错的事 ::
你需要意识到 C 中的所有东西都是按值传递的,所以如果你传递一个指针,那个指针也是按值传递的。因此,当您的老师告诉您使用 TypeSCL* pscl
时,它的意思是 NodeSCL **pscl
,她是对的,因为您不能使用 NodeSCL *pscl
,这可能有助于您理解我为什么这样说 :: What is the reason for using a double pointer when adding a node in a linked list?
此外,在您的情况下,当 pscl == NULL
首先应该是 *pscl == NULL
您需要将 *pscl
设置为您的新节点。
接下来,如果你想在最后添加一个新节点,你应该使用一个while循环,正如@Neha Chauhan所提到的。
接下来,您使用的最后两个语句::
(*temp)->next = (*pscl)->next;
(*pscl)->next = *temp;
您正在将新添加节点的 next
设置为链表的第二个元素,这没有任何意义。
我已经使用变量NodeSCL *tempCheck
移动到了链表的最后一个节点!
所以,最后两行应该像
tempCheck->next = temp;
temp->next = (*pscl);
最后,兄弟,你需要通过指导来提高你的基础知识。 (别介意!)
编辑::
为什么你的测试在没有最后两行的情况下也能工作::因为,对于你编写的代码,你的链表的大小始终为 1,第一个元素之后没有添加任何元素!因此,测试运行,但失败了!
我会尽量说清楚。
我在名为 "esercizio.h":
的文件中有这个结构(由于我的老师,我无法更改它)#ifndef ESERCIZIO_H
#define ESERCIZIO_H
struct ElemSCL{
int info;
struct ElemSCL* next;
};
typedef struct ElemSCL NodoSCL;
typedef NodoSCL* TipoSCL;
void accoda(TipoSCL* pscl, int i);
#endif
函数"accoda"必须在循环链表(由TipoSCL* pscl 指向)的末尾添加一个元素(int i)。我试图将函数体写在一个名为 "esercizio.c":
的文件中#include <stdio.h>
#include <stdlib.h>
#include "esercizio.h"
void accoda(TipoSCL* pscl, int i){
NodoSCL* temp = (NodoSCL*) malloc(sizeof(NodoSCL));
temp->info = i;
temp->next = temp;
if (pscl == NULL){
return;}
while ((*pscl)->next != *pscl){
*pscl = (*pscl)->next;}
(*temp)->next = (*pscl)->next; //Problems starts here
(*pscl)->next = *temp;
}
正如我在我的代码中让您注意到的那样,如果我不添加最后两行,一切正常。如果函数中没有 TypeSCL* 而是 NodeSCL* 我会使用:
temp->next = pscl->next;
pscl->next = temp;}
但是我的老师决定使用 TypeSCL* pscl 而不是 NodeSCL* pscl。
我有一个 "test.h" 文件...
#include "esercizio.h"
#ifndef TEST_H
#define TEST_H
char* toString(TipoSCL scl);
#endif
...和一个 "test.c" 文件,带有 main() 函数和所有让我检查我的代码是否正常工作的输入:
#include <stdlib.h>
#include <string.h>
#include "../libtest/libtest.h"
#include "test.h"
#include "esercizio.h"
const int NTEST=5;
TipoSCL input[5];
int add[5] = {1,2,3,4,5};
TipoSCL expected[5];
int main(int argc, char** argv){
input[0] = NULL;
input[1] = (TipoSCL) malloc(sizeof(NodoSCL));
input[1] -> info = 1;
input[1] -> next = input[1];
input[2] = (TipoSCL) malloc(sizeof(NodoSCL));
input[2] -> info = 1;
input[2] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[2] -> next -> info = 2;
input[2] -> next -> next = input[2];
input[3] = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> info = 1;
input[3] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> next -> info = 2;
input[3] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> next -> next -> info = 3;
input[3] -> next -> next -> next = input[3];
input[4] = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> info = 1;
input[4] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> info = 2;
input[4] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> next -> info = 3;
input[4] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> next -> next -> info = 4;
input[4] -> next -> next -> next -> next = input[4];
expected[0] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[0] -> info = 1;
expected[0] -> next = expected[0];
expected[1] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[1] -> info = 1;
expected[1] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[1] -> next -> info = 2;
expected[1] -> next -> next = expected[1];
expected[2] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> info = 1;
expected[2] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> next -> info = 2;
expected[2] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> next -> next -> info = 3;
expected[2] -> next -> next -> next = expected[2];
expected[3] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> info = 1;
expected[3] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> info = 2;
expected[3] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> next -> info = 3;
expected[3] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> next -> next -> info = 4;
expected[3] -> next -> next -> next -> next = expected[3];
expected[4] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> info = 1;
expected[4] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> info = 2;
expected[4] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> info = 3;
expected[4] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> next -> info = 4;
expected[4] -> next -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> next -> next -> info = 5;
expected[4] -> next -> next -> next -> next -> next = expected[4];
test_reset();
for (int i = 0; i < NTEST; i++) {
print_test_start(i+1);
printf("Funzione: accoda\n");
printf("Input: %s\n", toString(input[i]));
accoda(&input[i],add[i]);
test_compare_strings(toString(expected[i]),toString(input[i]));
print_test_end();
print_n_success("#Test superati: ");
}
print_test_result("Percentuale test corretti:");
}
char* toString(TipoSCL scl){
char* res = (char*) malloc(200*sizeof(char));
res[0] = '[';
res[1] = '[=14=]';
TipoSCL aux = scl;
if (aux != NULL) {
char buf[10];
do{
sprintf(buf,"%d->",aux -> info);
strcat(res,buf);
aux = aux -> next;
}
while(aux != scl);
sprintf(buf,"|%d",aux -> info);
strcat(res,buf);
aux = aux -> next;
}
strcat(res,"]");
return res;
}
我的代码 "everything is ok if I don't add the lasts two rows" 是什么意思? 当我 运行 我的程序(感谢终端和 cd 和 make )没有
(*temp)->next = (*pscl)->next; //Problems starts here
(*pscl)->next = *temp;
测试 运行 没有问题(当然,它说我没有一个正确的结果。但是如果我将这两行添加到我的代码中,我得到 "Segmentation fault: 11"。
我认为你的 pscl 指针必须到达链表的末尾,然后它应该插入临时元素。 你能做的是
void add(TypeSCL* pscl, int i){
NodeSCL* temp = (NodeSCL*) malloc(sizeof(NodeSCL));
temp->info = i;
temp->next = temp;
if (pscl == NULL){
return;
while(pscl->next != pscl)
pscl = pscl->next;
temp->next = (*pscl)->next; //THINGS GO WRONG HERE...
(*pscl)->next = temp; //...AND HERE
}
'
尝试将您的添加函数更改为此 ::
void add(TypeSCL* pscl, int i){
NodeSCL* temp = (NodeSCL*) malloc(sizeof(NodeSCL));
temp->info = i;
temp->next = temp;
if (*pscl == NULL){
*pscl = temp;
return;}
NodeSCL *tempCheck = *pscl;
while(tempCheck->next != *pscl) {
tempCheck = tempCheck->next;
}
tempCheck->next = temp;
temp->next = (*pscl);
}
你做错的事 ::
你需要意识到 C 中的所有东西都是按值传递的,所以如果你传递一个指针,那个指针也是按值传递的。因此,当您的老师告诉您使用 TypeSCL* pscl
时,它的意思是 NodeSCL **pscl
,她是对的,因为您不能使用 NodeSCL *pscl
,这可能有助于您理解我为什么这样说 :: What is the reason for using a double pointer when adding a node in a linked list?
此外,在您的情况下,当 pscl == NULL
首先应该是 *pscl == NULL
您需要将 *pscl
设置为您的新节点。
接下来,如果你想在最后添加一个新节点,你应该使用一个while循环,正如@Neha Chauhan所提到的。
接下来,您使用的最后两个语句::
(*temp)->next = (*pscl)->next;
(*pscl)->next = *temp;
您正在将新添加节点的 next
设置为链表的第二个元素,这没有任何意义。
我已经使用变量NodeSCL *tempCheck
移动到了链表的最后一个节点!
所以,最后两行应该像
tempCheck->next = temp;
temp->next = (*pscl);
最后,兄弟,你需要通过指导来提高你的基础知识。 (别介意!)
编辑::
为什么你的测试在没有最后两行的情况下也能工作::因为,对于你编写的代码,你的链表的大小始终为 1,第一个元素之后没有添加任何元素!因此,测试运行,但失败了!