1

我使用 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--;
                    }

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

4

3 回答 3

2

在这一行:

index_change=p_node->next_node;

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

于 2013-10-08T06:58:02.670 回答
1

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

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

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

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

于 2013-10-08T07:18:19.560 回答
0

在这一行:

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

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

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

于 2013-10-08T07:03:53.930 回答