gpt4 book ai didi

c - 链表 — 删除包含素数的节点

转载 作者:行者123 更新时间:2023-11-30 21:19:53 26 4
gpt4 key购买 nike

我用 C 语言编写了一段代码,它将创建一个链接列表。链表结构有两个字段,即 datanextdata 包含整数数据,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;
}
}

最佳答案

问题出在这里:

while (temp != NULL) {
N = temp->next->data;

当到达列表的最后一个元素时,temp 不是 NULL,但 temp->nexttemp ->next->data 具有未定义的行为。

还有其他问题:

  • 您的 prime() 函数效率低下,对于 01 将返回 1
  • 您的deletetheprime()函数删除节点并更新调用者作用域中的指针,但调用者不会更新前一个节点中的链接,也不会更新H指针如果删除的节点是第一个。
  • 如果没有充分的理由使用全局变量,您应该将 H 传递给 display() 并将所有变量设置为 main() 中的本地变量.
  • 您永远不会释放已分配的对象,释放您分配的所有内容是一种很好的风格。
  • 你不应该将指针隐藏在typedef后面,将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;
}
<小时/>

我将你的请解决它!的立场归因于你的英语水平不佳。请仔细研究本网站上的答案,以提高您的沟通能力和编程技能。

关于c - 链表 — 删除包含素数的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45662344/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com