我用C语言编写了一个代码,用于创建链接列表。链表结构有两个字段,即data
和next
; data
包含整数数据,next
是结构指针。
程序要求用户将数据输入列表。输入数据后,程序将浏览列表并检查节点中哪些数据包含素数。如果它找到一个这样的节点,它将删除它并将下一个节点链接到前一个节点,但是我收到了一个分段错误错误,我无法解决。
我在代码下面。 你能不能帮助我解决它,因为我不知道如何找到问题?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
typedef struct node *nptr;
nptr H, h, n;
void deletetheprime(struct node**);
void display();
int prime(int);
int main() {
nptr temp1, temp;
int i, N, p;
printf("\n if list is completed enter 999\n");
for (;;) {
printf("\n enter the data \n");
scanf("%d", &i);
if (i == 999)
break;
else
if (H == NULL) {
H = h = (nptr)malloc(sizeof(struct node));
H->data = i;
H->next = NULL;
} else {
n = (nptr)malloc(sizeof(struct node));
n->data = i;
n->next = NULL;
h->next = n;
h = n;
}
}
printf("\n data before deletion\n");
display();
temp = H;
while (temp != NULL) {
N = temp->next->data;
p = prime(N);
if (p == 1) {
deletetheprime(&temp);
} else {
temp = temp->next;
}
}
printf("\n the data after deletion is\n");
display();
return 0;
}
void deletetheprime(struct node **temp2) {
nptr temp, temp1;
temp = *temp2;
temp1 = temp->next;
temp->next = temp->next->next;
free(temp1);
temp = temp->next;
}
int prime(int i) {
int j, p = 0;
for (j = 2; j <= i / 2; i++) {
if (i % j == 0) {
break;
}
}
if (j > i / 2) {
p = 1;
}
return p;
}
void display() {
nptr temp;
temp = H;
while (temp != NULL) {
printf("\n %d", temp->data);
temp = temp->next;
}
}
答案 0 :(得分:1)
问题出现在主
中temp
您正在检查NULL
是否不是next
,这是正确的,但访问NULL
节点的数据,可以为NULL
, 在列表末尾附近while(temp!=NULL)
{
N=temp->data;
...
,这会导致未定义的行为。
只需将其修改为
即可NULL
你确定temp不是temp->next->next
,你在这里不会得到分段错误。而且它会起作用。
或者,如果您需要访问next->next
节点的数据,则必须检查NULL
是否也不是while(temp!=NULL)
{
if (temp->next->next != NULL)
{
N=temp->next->data;
}
else // temp->next->next is NULL so you can't access the data
...
。
react-native run-android
答案 1 :(得分:1)
问题在于:
while (temp != NULL) {
N = temp->next->data;
当您到达列表的最后一个元素时,temp
不是NULL
,但temp->next
是temp->next->data
具有未定义的行为。
还有其他问题:
prime()
函数效率低下,将1
和0
返回1
。deletetheprime()
函数删除节点并更新调用者范围中的指针,但如果删除的节点是第一个节点,则调用者不会更新前一节点中的链接,也不更新H
指针。 H
传递给display()
并将所有变量设为main()
。node
成为struct node
的typedef,但保持指针可见,这是一个避免让读者和程序员混淆的好习惯。要删除节点,您应该使用指针链接技巧:
for (struct node **p = &H; *p;) {
if (prime((*p)->data) {
nptr np = *p;
*p = np->next;
free(np);
} else {
p = &(*p)->next;
}
}
p
最初指向头指针H
,然后指向前一个节点的next
成员。当找到要删除的节点时,它可用于更新前一节点中的头指针或链接。
以下是更正后的简化版本:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
int isprime(int n) {
if (n < 2)
return 0;
if (n % 2 == 0)
return n == 2;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
void display(const node *temp) {
while (temp != NULL) {
printf(" %d", temp->data);
temp = temp->next;
}
printf("\n");
}
int main(void) {
node *H = NULL;
node **lastp = &H;
node *n;
int i;
printf("Enter values, when list is completed enter 999\n");
for (;;) {
printf("\n enter the data: ");
if (scanf("%d", &i) != 1 || i == 999)
break;
n = malloc(sizeof(*n));
if (n == NULL)
break;
n->data = i;
n->next = NULL;
*lastp = n;
lastp = &n->next;
}
printf("\n data before deletion: ");
display(H);
for (node **p = &H; *p;) {
if (isprime((*p)->data)) {
n = *p;
*p = n->next;
free(n);
} else {
p = &(*p)->next;
}
}
printf("\n the data after deletion is: ");
display(H);
/* free the list */
while (H != NULL) {
n = H;
H = n->next;
free(n);
}
return 0;
}
我将把你的归结为你解决它!对你糟糕的英语语言的立场。请通过仔细研究本网站的答案,学习如何改善沟通和编程技巧。