2016-10-01 6 views
1

私は周りを読んでいますが、私はまだリンクされたリストを理解するのに苦労しています。私の問題は、何らかの理由でリストを走査して、リスト内の構造の名前や年齢が同じかどうかを調べるときです。リストを削除するときや、新しいノードをリストに追加しようとしたときにも削除されます。C - リンクされたリストにアルファベット順に新しいノードを挿入

リストは動的なので、どのタイプのカウントにも基づいていませんが、ユーザーが入力することを決めた構造の数です。

いずれの方向にも感謝します。

int add(char* name, char* genderValueString, char* breed, int age, float weight) 
{ 

int result; 
int count = 0; 
gender curGen = 1; 


struct dog *temp = malloc(sizeof(struct dog)); 

strcpy(temp->name, name); 
strcpy(temp->breed, breed); 
temp->age = age; 
temp->weight = weight; 

if (strcmpi(genderValueString, "male") == 0) { 
    curGen = 0; 
} 
temp->genderValue = curGen; 


if (list == NULL) { 
    temp->next = list; 
    list = temp; 
    result = 1; 
} 

else { 

    while (list != NULL) { 
     if (strcmpi(list->name, name) == 0 && list->age == age) { 
      result = 0; 
     } 

     else { 
      result = 1; 
     } 

     list = list->next; 
    } 


    if (result == 1) { 
     while (list != NULL) { 

      if (strcmpi(list->name, name) > 0 || list->age > age) { 

       struct dog *prev = list; 
       list = temp; 
       list->next = prev;    

      } 

      list = list->next; 
     } 


    } 

} 


return result; 
} 

答えて

0

私はあなたの変数listはあなたのリストの先頭を表し、グローバル変数であることを想像してみてください。

コードの主な問題は、whileループ(list = list->next)でlistを修正していることです。つまり、頭の軌跡が失われています。

コードを動作させるために今できることは、頭のコピーであり、安全に変更できる別の変数を宣言することです。例えば

struct dog *list_tmp; 

... 

for (list_tmp = list; list_tmp != NULL; list_tmp = list_tmp->next) 
{ 
    if (strcmpi(list->name, name) == 0 && list->age == age) { 
     result = 0; 
    } 
    ... 
} 

そして、あなたの二つのループのためにそれを行います。

しかし、あなたのリストの頭の唯一のコピーのようですので、一番下の行は、決してlistを変更しません。)

+0

ありがとうございますが、私はまだ少し問題があります。リストに何かを追加したいのであれば、それをlist_tmpに追加して、古いリストを一時リストと同じにするか、それとも元のリストに直接追加するだけですか? – poomulus

0

は、私はあなたが現在の頭部を追跡する必要があるのVisual Studio 2013でこれをテストしましたリスト。私はこの世界をdoglistと名づけました。次に、ローカル変数listを使用してリストを移動します。 1つのトリッキーなケースがあります。リストの先頭に挿入すると、これをリストの新しい頭にする必要があります。

struct dog 
{ 
    char name[50]; 
    int genderValue; 
    char breed[50]; 
    int age; 
    float weight; 
    struct dog * next; 
}; 

struct dog *doglist = NULL; 

int dogadd(char* name, char* genderValueString, char* breed, int age, float weight) 
{ 
    struct dog * list = doglist; // save head of list 
    int count = 0; 
    int curGen = 1; 

    struct dog *temp = (dog *)malloc(sizeof(struct dog)); 
    strcpy(temp->name, name); 
    strcpy(temp->breed, breed); 
    temp->age = age; 
    temp->weight = weight; 

    if (strcmpi(genderValueString, "male") == 0) { 
     curGen = 0; 
    } 
    temp->genderValue = curGen; 

    if (list == NULL) { 
     temp->next = list; 
     doglist = temp; 
     return 1; 
    } 

    while (list != NULL) { 
     if (strcmpi(list->name, name) == 0 && list->age == age) { 
      return 0; 
     } 
     list = list->next; 
    } 

    list = doglist;    // restore the head of the list 
    struct dog * prev = NULL; // keep the previous list node so we can point it to the inserted entry 
    while (list != NULL) { 
     int nameCompare = strcmpi(list->name, name); 
     if (nameCompare > 0 || (nameCompare == 0 && list->age > age)) { 

      temp->next = list; 
      if (prev != NULL) 
       prev->next = temp; 
      // if we are inserting before the current head of the list we need to make this the new head 
      if (list == doglist) 
       doglist = temp; 
      list = temp; 
      return 1; 
     } 
     if (list->next == NULL) { 
      // Nothing greater than this, so add it to end 
      list->next = temp; 
      temp->next = NULL; 
      return 1; 
     } 
     prev = list; 
     list = list->next; 
    } 
    return 0; 
} 

void main() 
{ 
    dogadd("Sybil", "female", "red heeler", 7, 40.1); 
    dogadd("Pepi", "male", "chihuahua", 5, 3.3); 
    dogadd("Goliath", "male", "bulldog", 9, 20.5); 
    dogadd("Harry", "male", "golden retriever", 9, 35.6); 
    dogadd("ZsaZsa", "female", "poodle", 3, 10.5); 
    dogadd("Bruce", "male", "german shepherd", 9, 42.7); 
    dogadd("Sybil", "female", "red heeler", 7, 40.1); // check it isn't added again 
    struct dog * list = doglist; 
    while (list != NULL) { 
     printf("Dog name=%s sex=%d, breed=%s, age=%d, weight=%f\n", list->name, list->genderValue, list->breed, list->age, list->weight); 
     list = list->next; 
    } 
} 
+0

アドバイスをありがとう、私はまだ私がリストにいくつかの名前を追加することができますが、その後停止するこの問題に実行しています。 – poomulus

+0

おっとり - 前のリストノードを新しく挿入されたノードに向けるのを忘れました。私は2つの既存のエントリの間に新しいエントリを挿入したテストケースを持っていませんでした。このエントリはこのバグを公開していました。 –

+0

本当にありがとうございました。これはリンクされたリストがどのように機能するかを明確にしました。 – poomulus

関連する問題