单链表的数组不会删除节点

时间:2017-10-25 22:54:39

标签: c arrays linked-list

我有一个数组[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;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

当您按p删除时,您在previous循环内声明新变量forsize。因此,当循环后的代码使用这些变量时,它使用在函数顶部声明的未初始化变量。摆脱声明,只需分配变量。

此外,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;
            }
        }
    }