2013-10-08 59 views
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--; 
        } 

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

+0

“程序崩溃” - >崩溃如何?请使用调试器来查看确切的问题。另外,你最有可能泄漏内存 - 你不会将代码显示在创建列表的位置,但很可能你是新建的一些节点。但是在上面显示的代码中,您从不为从列表中删除的节点执行“删除”操作 – codeling

+0

在分配head = NULL后,您可能已经解除引用head。 –

+0

我应该发布完整的程序吗? – APan

回答

2

在这一行:

index_change=p_node->next_node; 

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

+0

哎呀,我错过了。你是对的。 – APan

0

在这一行:

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

你通过head指针,如果你尝试删除第一个节点,其已被设置为NULL

所以你不能取消head函数里面的search函数,你的代码必须做的(因为我相信),因为你没有任何其他的方式来到链接列表的开始。

+0

,但当头部为空时,不会访问p_node = search(head,key,&cur)行。如果这个列表至少有一个值,或者当head!= NULL,那么只有这一行会被访问。 – APan

+0

@AdarshPanicker:对,我错过了! –

1

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

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

此外,你的程序结构非常糟糕。考虑将特定的操作转移到单独的函数中,并为每个函数编写测试。这也可以让你发布一个简明,完整的代码示例与你的问题。

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

+0

@Pollex我现在已经发布了完整的代码。 – APan

+0

发现错误。是的,也许如果我会制作更多结构化的程序,我自己会想出错误。感谢名单 – APan