2016-01-10 22 views
1

我有問題,從列表中刪除元素刪除鏈表元素,直到我找到單詞

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MAX 30 

typedef struct elem{ 

    char name[MAX]; 
    int statistic; 
    int price; 

    struct elem *next; 
    struct elem *prev; 

} shop; 

我在列表中搜索主定義的話造成的功能,然後,如果它發現它,它保持刪除1 ST元素,直到找到單詞,然後將其刪除所選的詞,使未來的第一:

void delete_from_list(shop *first, char word[MAX], int* check) 
{ 
    shop *tmp= first; 
    while (tmp!=NULL && strcmp(tmp->name, word) != 0) 
    { 
     tmp = tmp->next; 
    } 

    if (tmp != NULL && strcmp(tmp->name, word)==0) 
    { 
     printf("FOUND!"); 
    } 
    else 
    { 
     *check=1; 
    } 
    if (check==0) 
    { 
     while (strcmp(first->name, tmp->name)!=0) 
     { 
      first=first->next; 
      free(first->prev); 
      first->prev=NULL; 
     } 
     first=first->next; 
     free(first->prev); 
     first->prev=NULL; 
    } 
} 

void print_list(shop *first) 
{ 
    first=first->next; 

    if(first->name==NULL) 
     printf("There is nothing!!!\n"); 

    while(first->next!=NULL){ 

     printf("%20s",first->name); 
     printf("%20d \t\t",first->statistic); 
     printf("%d\n",first->price); 

     first=first->next; 
    } 

} 

我打印的清單,然後取詞。

main() 
{ 
    int check = 0; 

    print_list(first); 
    scanf("%s", word); 

    delete_from_list(first, word, &check); 

    if (check!=1) 
    { 
     print_list(first); 
    } 
    else 
    { 
     check=0; 
    } 
} 

問題是,鏈表不會如何改變,所以我應該添加指針,但我不知道如何。

+1

你真的應該顯示一些輸入,什麼是預期的,以及你得到了什麼。 – coredump

+0

你的意圖不明確。如果元素不是**,您是否希望**完整列表**被刪除? – wildplasser

回答

1

您必須通過參考傳遞指針first

此功能還有一個錯誤。找到的元素後面的下一個元素可以等於NULL。在這種情況下,這些陳述

first=first->next; 
    free(first->prev); 
     ^^^^^^^^^^^ 
    first->prev=NULL; 
    ^^^^^^^^^^^ 

導致未定義的行爲。

該函數可以寫成下面的方式

void delete_from_list(shop **first, const char *word, int *check) 
{ 
    shop *tmp = *first; 

    while (tmp!=NULL && strcmp(tmp->name, word) != 0) 
    { 
     tmp = tmp->next; 
    } 

    if (tmp != NULL) 
    { 
     printf("FOUND!"); 
    } 
    else 
    { 
     *check = 1; 
    } 

    if (check == 0) 
    { 
     tmp = tmp->next; 
     while (*first != tmp) 
     { 
      shop *current = *first; 
      *first = (*first)->next; 
      free(current); 
     } 
     if (*first) (*first)->prev = NULL; 
    } 
} 

而且這是一個不好的設計,該函數依賴於在主設定的check值。如果函數本身設置變量check會更好。在這種情況下,您可以將該功能分成兩個功能。第一個將搜索目標元素,第二個將刪除滿足條件的所有元素(如果需要的話)。

我會定義函數通過以下方式

int delete_from_list(shop **first, const char *word) 
{ 
    shop *tmp = *first; 
    int deleted = 0; 

    while (tmp!=NULL && strcmp(tmp->name, word) != 0) 
    { 
     tmp = tmp->next; 
    } 

    if (tmp != NULL) 
    { 
     deleted = 1; 

     tmp = tmp->next; 
     while (*first != tmp) 
     { 
      shop *current = *first; 
      *first = (*first)->next; 
      free(current); 
     } 
     if (*first) (*first)->prev = NULL; 
    } 

    return deleted; 
} 

也起到print_list也是錯誤的。一般參數firstfirst->next可以等於NULL。在這種情況下,像這樣的陳述

first=first->next; 
if(first->name==NULL) 
while(first->next!=NULL){ 

導致未定義的行爲。

而功能的邏輯本身是錯誤的。

1

首先,您必須採用函數delete_from_list, 的參數列表,以便能夠刪除第一個元素。使用shop **first而不是 shop *first。使用nameword查找元素只要第一個元素不是找到的元素,就刪除列表中的第一個元素。

void delete_from_list(shop **first, char word[MAX], int* check) 
         // ^^ pointer to pointer of first element 
{ 
    // search for elemnt with name word 
    shop *found = *first; 
    while (found != NULL && strcmp(found->name, word) != 0) 
     found = found ->next; 

    if (found != NULL) 
    { 
     // found is element with name word 
     printf("FOUND!"); 

     // Delete the first element of your list as long as first elment is not found element 
     shop *temp = *first; 
     while (temp != found) 
     { 
      shop *next = temp->next;  
      free(temp); 
      temp = next; 
     } 

     *first = found;  // write back the new first element of your list 
     (*first)->prev = NULL; // predecessor of first element is NULL 
    } 
    else 
     *check=1; 
} 
+0

它運行良好,但它刪除了1個elem。 – Rosolak

+0

@Rosolak我改進了我的答案。 – Rabbid76