c语言 - 为什么不能直接删除第一个节点(头节点)?



>我使用 c 创建了一个简单的链表,我们可以在其中插入和删除列表中的任何位置的元素。代码工作正常,直到我尝试使用以下代码删除第一个节点。

typedef struct l_list
{
    int data,index;
    struct l_list *next_node;
}node;
static int total_node=0;
node *search(node *,int,node **);
int main()
{
int choice,key;
char ans;
node *new_node,*head, *p_node,*index_change,*cur;
node *get_node();
head=NULL;

printf("Program for Linked List.n");
do
{
    printf("n1. Create Node");
    printf("n2. Delete Node");
    printf("n3. Traverse the List");
    printf("n4. Exit");
    printf("nEnter your choice: ");
    scanf("%d",&choice);
    switch(choice)
    {
        case 1:
            do
            {
                total_node++;
                new_node=get_node();
                printf("nEnter the data you want to insert: ");
                scanf("%d",&new_node->data);
                if(head==NULL)
                {
                    head=new_node;
                    head->index=1;
                }
                else
                {
                printf("nWhich node you want to insert it as:n");
                for(int i=1;i<=total_node;i++)
                {
                    printf("%d ",i);
                }
                printf("==) ");
                scanf("%d",&key);
                //printf("bb-|-");
                if(key==1)
                {
                    new_node->next_node=head;
                    head=new_node;
                }
                else
                {
                    p_node=search(head,key,&cur);
                    new_node->next_node=p_node->next_node;
                    p_node->next_node=new_node;
                //p_node=NULL;
                }
                new_node->index=key;
                index_change=new_node->next_node;
                while(index_change!=NULL)
                {
                    index_change->index=++key;
                    index_change=index_change->next_node;
                }
                }
                printf("nDo you want to insert more node in the linked list: [y/n]");
                //ans=getch();
            }while((ans=getch())=='y');
            break;
//Deletion code.
case 2:
            do
            {
                if(head==NULL)//head is first node of the list
                {
                    printf("nUNDERFLOW!nThe linked list is already empty.n");
                }
                else
                {
                    printf("Which node you want to delete:n");
                    for(inti=1;i<=total_node;i++)
                        printf("%d ",i);  //total_node=variable taken
                    printf("==) ");      //to track the total no of node
                    scanf("%d",&key); //key=node index to be deleted
                    //printf("bb-|-");
                    if(key==1)
                    {
        //If we need to delete the first node when only one node is left                
                            if(total_node==1)
                            {
                            //p_node=head;
                            head=NULL;
                            }
                //If we need to delete the first node when more than one node are there
                        else
                            {
                            //p_node=head;
                            head=head->next_node;
                            }
                        total_node--;
                    }
                    else
                    {
                        p_node=search(head,key,&cur);//returns node just before the node to be deleted
                        p_node->next_node=cur->next_node;//cur gets the value of the node that is to be deleted.
                        total_node--;
                    }
                    index_change=p_node->next_node;
                    while(index_change!=NULL)//to change the index of following nodes.
                    {
                        index_change->index=key++;
                        index_change=index_change->next_node;
                    }
                }
                printf("nDo you want to delete more nodes: [y/n]n");
            }while((ans=getch())=='y');
case 3:
        if(head==NULL)
            printf("nThe linked list is empty.n");
        else
        {
            printf("nThe elements of linked lists are as follows:nn");
            p_node=head;
            while(p_node!=NULL)
            {
                printf("[%d]->%d  ",p_node->index,p_node->data);
                p_node=p_node->next_node;
            }
        }
        break;

    }
}while(choice!=4);

return 0;
}
    node *get_node()
    {
        node *temp1;
        temp1= new node;
        temp1->next_node=NULL;
        return temp1;
    }
    node *search(node *head,int key,node **cur)
    {
        node *current,*prev;
        current=head;
        while(current!=NULL)
        {                
            if(current->index==key)
            {
                return prev;
            }
            prev=current;
            current=current->next_node;
            *cur=current;
        }
        return prev;
    }

如果我尝试删除第一个节点,请使用此代码,程序会崩溃。当我使用临时变量时,例如

if(key==1)
                    {
                        if(total_node==1)
                            {
                            p_node=head;
                            head=NULL;
                            }
                        else
                            {
                            p_node=head;
                            head=p_node->next_node;
                            }
                        total_node--;
                    }

程序工作正常。所以我想问的是,我们可以直接删除头节点,还是总是需要另一个临时结构指针来删除头节点。

在这一行中:

index_change=p_node->next_node;

你取消引用p_node.但是,在删除第一个节点的情况下,不会为 p_node 设置值。您观察到的崩溃可能是因为p_node没有保存有效的内存地址。

如果没有您得到的确切错误和完整的程序,很难说发生了什么。

立即看起来错误的一件事是你分配节点(你的struct Linked_List),其中包括数据。这不是您想要的链表。在链表中,您只想修改指针,并阻止复制数据。

另外,你的程序结构非常糟糕。请考虑将特定操作移动到单独的函数中,并为每个函数编写测试。这也将允许您发布简洁、完整的代码示例以及您的问题。

为了消除错误,您可以使用调试器,也可以向代码中添加 print 语句,告诉您发生了什么。

在这一行中:

p_node=search(head,key,&cur);//returns node just before the node to be deleted

如果您尝试删除第一个节点,则传递head指针,该指针已设置为 NULL

因此,您不能取消引用代码必须执行的 search 函数中的head指针(我相信),因为您没有任何其他方法可以到达链表的开头。

相关内容

  • 没有找到相关文章

最新更新