gpt4 book ai didi

c - C语言如何删除链表中的某个元素

转载 作者:太空宇宙 更新时间:2023-11-04 08:32:29 26 4
gpt4 key购买 nike

我正在尝试删除链表中的某个元素。

当我在屏幕上打印所有元素时,它们有一定的顺序(见案例 2)。在情况 7 中,我可以根据该顺序选择要删除的元素。

情况 7 中的代码不起作用。这是我的代码:

#include "stdio.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"
#include "string.h"
#define SIZE 100
double dummy = sin(0.0);

struct sputnik {
char nazvanie[30];
char nazvanie_main[30];

int year;
float d;
int period;
struct sputnik *next;
};

int main(void) {
char choice;
int punkt;
int i, count = 0;
struct sputnik *head = NULL;
struct sputnik *prev, *current;
int res, kolvo, j, number;
struct sputnik a[SIZE];
system("clear");

while (1) {
printf("Menu: ");
printf("1- Create table with sputniks \n 2-All sputniks \n 3-Write 4-Read \n 5-Add \n 6-Change \n 7-Delete \n 8-Exit \n");
scanf("%d", &punkt);

while (getchar()!='\n')
continue;

switch(punkt) {
case 1:
while (1) {
printf("Create new table? (N-new; O-old)");
choice = toupper(getchar());
if (choice == 'N') {
count = 0;
prev = head;
while (prev != NULL) {
current = prev->next;
free(prev);
prev = current;
}
head = NULL;
}
if (choice != 'N' && choice != 'O') {
while (getchar() != '\n')
continue;
continue;
}
while (getchar()!='\n')
continue;
break;
}
for ( ; ; count++) {
current = (struct sputnik *)malloc(sizeof(struct sputnik));
if (head == NULL) {
head = current;
} else {
prev->next = current;
}
current->next = NULL;
printf("Name %d sputnika:", count + 1);
gets(current->nazvanie);
printf("Name planet:");
gets(current->nazvanie_main);
printf("Open year:");
scanf("%d", &current->year);
while (getchar() != '\n')
continue;
printf("Diameter:");
scanf("%f", &current->d);
while (getchar() != '\n')
continue;
printf("Period:");
scanf("%d", &current->period);
while (getchar() != '\n')
continue;
prev = current;
printf("Finish vvod?: y/n: \n");
if (toupper(getchar()) == 'Y') {
count++;
break;
} else {
while (getchar() != '\n')
continue;
continue;
};
}
break;
case 2:
if (head == NULL) {
printf ("No data \n");
} else {
printf(" Sputniks: \n");
}
current = head;
i = 0;
while (current != NULL) {
printf("%d sputnik - %s planet %s god %d diametr %4.3f period %d\n", ++i, current->nazvanie, current->nazvanie_main, current->year, current->d, current->period);
current = current->next;
}
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
int nummer;
printf("Number for sputnik to delete:\n");
scanf("%d", &nummer);
while (getchar() != '\n')
continue;
current = head;
i = 0;
while (current != NULL) {
if (i == nummer - 1) {
prev = current;
free(current);
current = prev->next;
} else {
current = current->next;
i = i + 1;
}
}
break;
case 8:
prev = head;
while (prev != NULL) {
current = prev->next;
free(prev);
prev = current;
}
printf("Finish \n");
return 0;
break;
default:
printf ("Dont right choose!\n");
break;
}
}
return 0;
}

最佳答案

您当前的算法已完全损坏。

  • 永远不要将已删除节点之前的节点与后续节点链接起来。
  • 您的算法根本不考虑删除头节点。
  • 即使在删除目标后,您也不必要地浏览列表的其余部分。

简而言之,这需要重新来过。

有多种方法可以做到这一点,许多方法至少使用一对指针(一个 prev 和一个 current)并将它们沿着列表向下移动,这似乎是您尝试过的以及几个答案试图解决的问题。不同的是,我将向您展示如何使用单个指针到指针来完成此操作。这样做的额外好处是无需特殊情况下的头指针检查。

包括基本的错误检查,它是这样完成的:

int nummer;
printf("Number for sputnik to delete:\n");
if (scanf("%d", &nummer) == 1 && nummer > 0)
{
struct sputnik** pp = &head;
while (--nummer && *pp)
pp = &(*pp)->next;;
if (*pp)
{
struct sputnik *p = *pp;
*pp = p->next;
free(p);
}
}
while (getchar() != '\n')
continue;

这遍历链表中的实际指针;不仅仅是他们的值(value)观。结果,当我们到达指向我们打算删除的节点的指针时,我们使用列表中的指针 将我们带到那里(如果请求是针对节点的,则包括头指针( 1)).这允许我们将该指针更新为其后继地址,然后删除该节点并完成。

当涉及到单链表操作时,指针到指针算法通常提供出奇优雅的解决方案和通常简洁的代码。盯着它看一会儿,或许可以将它与不同的二指针/三指针方法进行比较。

祝你好运。

关于c - C语言如何删除链表中的某个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27701322/

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