2013-10-08 93 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