我在删除列表中的元素时遇到问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 30
typedef struct elem{
char name[MAX];
int statistic;
int price;
struct elem *next;
struct elem *prev;
} shop;
我创建了一个函数,在列表中搜索一个在main中定义的单词,然后如果找到它,它会一直删除1 st 元素,直到它找到该单词,然后删除所选单词,然后将其作为第一:
void delete_from_list(shop *first, char word[MAX], int* check)
{
shop *tmp= first;
while (tmp!=NULL && strcmp(tmp->name, word) != 0)
{
tmp = tmp->next;
}
if (tmp != NULL && strcmp(tmp->name, word)==0)
{
printf("FOUND!");
}
else
{
*check=1;
}
if (check==0)
{
while (strcmp(first->name, tmp->name)!=0)
{
first=first->next;
free(first->prev);
first->prev=NULL;
}
first=first->next;
free(first->prev);
first->prev=NULL;
}
}
void print_list(shop *first)
{
first=first->next;
if(first->name==NULL)
printf("There is nothing!!!\n");
while(first->next!=NULL){
printf("%20s",first->name);
printf("%20d \t\t",first->statistic);
printf("%d\n",first->price);
first=first->next;
}
}
我打印清单然后说话。
main()
{
int check = 0;
print_list(first);
scanf("%s", word);
delete_from_list(first, word, &check);
if (check!=1)
{
print_list(first);
}
else
{
check=0;
}
}
问题是链表没有变化,所以我应该添加指针,但我不知道如何。
答案 0 :(得分:1)
您必须通过引用传递指针first
。
此功能也有错误。找到的元素之后的下一个元素可以等于NULL
。在这种情况下这些陈述
first=first->next;
free(first->prev);
^^^^^^^^^^^
first->prev=NULL;
^^^^^^^^^^^
导致未定义的行为。
该功能可以按以下方式编写
void delete_from_list( shop **first, const char *word, int *check )
{
shop *tmp = *first;
while ( tmp!=NULL && strcmp( tmp->name, word ) != 0 )
{
tmp = tmp->next;
}
if ( tmp != NULL)
{
printf("FOUND!");
}
else
{
*check = 1;
}
if ( check == 0 )
{
tmp = tmp->next;
while ( *first != tmp )
{
shop *current = *first;
*first = ( *first )->next;
free( current );
}
if ( *first ) ( *first )->prev = NULL;
}
}
这个函数依赖于在main中设置的check
的值,这是一个糟糕的设计。如果函数本身设置变量check
会更好。在这种情况下,您可以将功能拆分为两个功能。第一个将搜索目标元素,第二个将删除满足条件的所有元素(如果需要)。
我会按以下方式定义函数
int delete_from_list( shop **first, const char *word )
{
shop *tmp = *first;
int deleted = 0;
while ( tmp!=NULL && strcmp( tmp->name, word ) != 0 )
{
tmp = tmp->next;
}
if ( tmp != NULL)
{
deleted = 1;
tmp = tmp->next;
while ( *first != tmp )
{
shop *current = *first;
*first = ( *first )->next;
free( current );
}
if ( *first ) ( *first )->prev = NULL;
}
return deleted;
}
函数print_list
也是错误的。通常,参数first
或first->next
可以等于NULL
。在这种情况下,这些语句
first=first->next;
if(first->name==NULL)
while(first->next!=NULL){
导致未定义的行为。
这个函数的逻辑本身是错误的。
答案 1 :(得分:1)
首先,您必须采用函数delete_from_list
的参数列表,
这样它就能删除第一个元素。使用shop **first
代替
shop *first
。找到name
word
的元素。只要第一个元素不是找到的元素,就删除列表的第一个元素。
void delete_from_list(shop **first, char word[MAX], int* check)
// ^^ pointer to pointer of first element
{
// search for elemnt with name word
shop *found = *first;
while ( found != NULL && strcmp(found->name, word) != 0 )
found = found ->next;
if ( found != NULL )
{
// found is element with name word
printf("FOUND!");
// Delete the first element of your list as long as first elment is not found element
shop *temp = *first;
while ( temp != found )
{
shop *next = temp->next;
free( temp );
temp = next;
}
*first = found; // write back the new first element of your list
(*first)->prev = NULL; // predecessor of first element is NULL
}
else
*check=1;
}