为什么我不能直接删除第一个节点(头节点)?

时间:2013-10-08 06:53:15

标签: c linked-list singly-linked-list

我使用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("\b\b-|-");
                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("\b\b-|-");
                    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:\n\n");
            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--;
                    }

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

3 个答案:

答案 0 :(得分:2)

在这一行:

index_change=p_node->next_node;

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

答案 1 :(得分:1)

如果没有你得到的确切错误以及完整的程序,很难说出现了什么。

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

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

为了关闭错误,您可以使用调试器,也可以在代码中添加打印语句,告诉您发生了什么。

答案 2 :(得分:0)

在这一行:

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

如果您尝试删除第一个节点,则传递已设置为head的{​​{1}}指针。

所以你不能取消引用你的代码必须做的NULL函数内的head指针(我相信),因为你没有任何其他方法可以到达链表的开头