我有一个数组[4],其中数组的每个索引都有一个单链表,其中包含以下信息:name,size。 switch语句根据聚会的大小控制信息的索引。
问题:尝试根据大小(用户输入)删除节点时,节点不会删除。
我知道所有删除的情况都有正确的语法,但我无法弄清楚为什么我的节点不会删除。感谢任何帮助。
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
char name[20];
int size;
struct node *next;
}node;
node* head[4]={NULL,NULL,NULL,NULL};
node* tail[4]={NULL,NULL,NULL,NULL};
//
// proto's
//
void add_party(int, char name[], int size);
void delete_party(char name[], int size);
void list_parties(void);
void change_p_size(char name[], int size);
//
// main function
//
int main()
{
int x;
while (1)
{
fflush(stdin);
printf("\n\nEnter 1 to add a party\nEnter 2 to remove a party\nEnter 3 for the list of the party\nEnter 4 to change party size.\nEnter 5 to quit.\n\n");
// user interface
scanf("%d",&x);
switch(x)
{
char name[20]; //local variables
int size;
case 1:
printf("\nParty Name: ");
scanf("%s", name);
printf("\nParty Size: ");
scanf("%d", &size);
if(size == 0)
{
printf("\nThat is not a valid command. Party not added!\n");
}
if(size >= 1 && size <= 2)
{
add_party(0, name, size);
}
else if(size >= 3 && size <= 4)
{
add_party(1, name, size);
}
else if(size >= 5 && size <= 6)
{
add_party(2, name, size);
}
else if(size >= 7)
{
add_party(3, name, size);
}
break;
case 2:
printf("\nSize of party to delete: ");
scanf("%i", &size);
delete_party(NULL, size);
break;
case 3:
list_parties();
break;
case 4:
change_partysize();
break;
case 5:
exit(0);
default:
continue;
}
}
}
//
//add function
//
void add_party(int h, char *name, int size)
{
//create a new node
int i=0;
int breaker = 0;
node *p;
node *new_item;
new_item = (node *)malloc(sizeof(node)); // allocate memory the size of the struct
strcpy(new_item->name,name);
new_item->size = size;
if(head[h] == NULL && tail[h] == NULL) // if an empty list, create a head and tail
{
head[h] = new_item;
tail[h] = head[h];
new_item->next = NULL;
return;
}
//traversal
for(i=0; i<4; i++)
{
p = head[i];
while(p != NULL)
{
//check that no repeating names. delete nodes that do have repeating names
if(strcmp(p->name,name) == 0)
{
printf("\nSorry, that name is already taken\n");
free(new_item);
return;
}
p = p->next; //go to the next node in the list
}
}
tail[h]->next = new_item;
new_item->next = NULL;
tail[h] = new_item;
}
//
//delete function
//
void delete_party(char *name, int size)
{
int i=0;
int breaker = 0;
node *p;
node *previous;
if(name != NULL)
{
for(i=0; i<4; i++)
{
p = previous = head[i]; //make sure previous trails behind head
while(p != NULL)
{
int c = (strcmp(p->name,name)==0);
if(c==0)
{
breaker = 1;
break;
}
else
previous = p;
p = p -> next;
}
if(breaker==1)
break;
}
}
else
{
int group = -1;
if(size == 1 || size == 2)
{
group = 0;
}
if(size == 3 || size == 4)
{
group = 1;
}
if(size == 5 || size == 6)
{
group = 2;
}
if(size >= 7)
{
group = 3;
}
for(i = group; i > -1; i--)
{
node *p = head[i];
node *previous = head[i];
while(p != NULL)
{
if(p <= size)
{
breaker = 1;
break;
}
else
{
previous = p;
p = p-> next;
}
}
if(breaker)
break;
}
}
if(p == NULL)
return;
if(head[i] == tail[i] && head[i] != NULL) // case 1, empty list
{
printf("\nList is empty!\n");
return;
}
else if(p == tail[i] && p == head[i]) // case 2, one element
{
head[i] = NULL;
tail[i] = NULL;
free(p);
}
else if(p == head[i]) // case 3, delete from the head
{
head[i] = head[i] -> next;
tail[i] = NULL;
free(p);
}
else if(p == tail[i]) // case 4, delete from tail
{
tail[i] = previous;
tail[i] -> next = NULL;
free(p);
}
else // case 5, delete from middle
{
previous -> next = p -> next;
free(p);
}
}
//
// list function
//
void list_parties(void)
{
int i = 0;
node *p=head;
for(i=0; i<4; i++)
{
p=head[i];
while(p != NULL)
{
printf("\n\n%s, %d\n\n", p->name, p->size);
p=p->next;
}
}
}
//
// change function
//
void change_partysize(char *name, int size)
{
int absolute_value = 0;
int comparison = 0;
int current_size = 0;
printf("\nWhat name is your party under?\n");
scanf("%s", name);
//check if the name
printf("\nWhat would you like to change the size to?\n");
scanf("%d", &size);
node *p;
while(p != NULL)
{
if(p->name == name) //new size falls into same range as the size coorelating to the name
{
current_size = p->size;
absolute_value = abs(size - current_size);
comparison = size - current_size;
if(current_size > 7 && size > 7)
{
current_size = size;
return;
}
else if(absolute_value >= 1)
{
//delete the node's value but not the name
delete_party(NULL, size);
//insert node with new name & dif size
add_party(NULL, name, size);
}
else
{
printf("\nYou did not enter a different party size\n");
return;
}
}
}
}
答案 0 :(得分:1)
当您按p
删除时,您在previous
循环内声明新变量for
和size
。因此,当循环后的代码使用这些变量时,它使用在函数顶部声明的未初始化变量。摆脱声明,只需分配变量。
此外,if (p <= size)
似乎是if (p->size <= size)
的拼写错误。我很惊讶你没有得到编译器警告。
您还可以使用if(breaker)
标题中的测试替换for
项检查。
for(i = group; !breaker && i > -1; i--)
{
p = head[i];
previous = head[i];
while(p != NULL)
{
if(p->size <= size)
{
breaker = 1;
break;
}
else
{
previous = p;
p = p-> next;
}
}
}