2015-12-17 44 views
1

我正在嘗試爲聖誕節做一個程序!我的知識是有限的;我迷失在指針和循環等中,我一直在想這個幾個小時。C - 根據值移動或刪除多個節點

我有一個指針數組來單鏈表。每個數組索引表示兒童的年齡組0的列表:0-3,1:4-7,2:8-11,3:11 - 15

每個孩子都是一個struct,每年我現在後想要遍歷所有列表,將其年齡增加1,如果他們需要更改年齡組,則必須將節點移至包含該年齡組的適當列表。如果孩子的年齡超過15歲,則必須刪除該節點。我的代碼是不完整的,因爲我是鏈接列表的新手,我感到困惑。

我的主要問題是當我移動它們時,我對列表進行了更改,因此如果我檢查第一個節點並刪除它,我必須再次檢查第一個節點,因爲現在它是一個新節點,所以我繼續檢查,直到頭部沒問題,這是正確的方法嗎?我不確定我的代碼是否有效,但我無法測試它。

部分從我Santa_Claus.h:

/*Structure defining a node of the children list*/ 
struct child { 
    int cid; /*The identifier of the child.*/ 
    int age; /*The age of the child.*/ 
    int did; /*The identifier of the child.*/ 
    int present_choices[M]; /*The array in which the preferences of the child for presents are stored*/ 
    struct child *next; /* Singly-linked, sorted by id */ 
}; 

部分從Santa_Claus.c

#define N 4 /*Number of children's age categories*/ 
struct child *Age_categories[N]; 

int new_season(void) { 
    int i; 
    struct child *childP = NULL; 
    struct child *prev = NULL; 
    struct child *childptr = NULL; 
    int MaxAges[N] = {3,7,11.15}; 

    //Increment Age Loop 
    for(i = 0; i < N; i++){ 

    childP = Age_categories[i]; 
     while(childP != NULL){ 
      childP->age = childP->age + 1; 
      childP = childP->next; 
     } 
    } 

    //Remove or Move Loop 
    for(i = 0; i < N; i++){ 
     childP = Age_categories[i]; 

     //while the first is still > than the max age of this category 
     while(childP->age > MaxAges[i]){ 
       if(i != (N-1)){ 
        childP->next = Age_categories[i+1]; 
        Age_categories[i+1] = childP; 
       }else{ 
        Age_categories[i] = childP->next; 
       } 
       childP = childP->next; 
     } 



     prev = Age_categories[i]; 
     childP = prev->next; 

     while(childP != Null){ 

      if(childP->age > MaxAges[i]){ 
       if(i != (N-1)){ 
        prev->next = childP->next; 
        childP->next = Age_categories[i+1]; 
        Age_categories[i+1] = childP; 
       }else{ 
        Age_categories[i] = childP->next; 
       } 

      } 
      prev = childP; 
      childP = childP->next; 
     } 

    } 

    return 1; 
} 
+1

問題是什麼/問題嗎? –

+1

需要「漂亮/淘氣」布爾型。 –

+0

@AntoineMathys感謝您的時間採取LO好吧。我猜我必須回過頭來逐一對列表進行排序,我想呢?即使它效率不高。當我在列表中移動時,有太多的事情正在進行,我迷了路! –

回答

0

我的主要問題是,我更改了名單,因爲我通過他們移動,所以如果我檢查第一個節點並刪除它,我必須再次檢查第一個節點,因爲現在它是一個新節點,所以我繼續檢查,直到Head沒問題,這是正確的方法嗎?

就地編輯會咬你邊緣情況。你會遇到頭部和尾部節點的問題。如果你移除了頭部,那麼無論是跟蹤你的頭部現在指向零空間。

總之,你就必須要小心。有很多方法可以把它搞砸。而對於新手來說,我建議你遠離C中的指針。強大的,但屁股疼痛。堅持固定陣列,除非你真的需要這個東西來擴展。

你並不需要重新檢查頭這麼多,因爲有一個特殊的情況下,檢查頭,並做頭部安全的編輯。同時檢查該設備是否爲空,並檢查尾部通常是好主意。你可以嘗試找出一些聰明的東西來避免這種事情,並且有平滑的代碼來處理這些事情......但聰明的代碼經常會讓你像屁股一樣多。

+0

這是一個任務我有,所以我想我會想出來最終我希望,有一個愉快的一天,並感謝您花時間爲此,每一個建議的讚賞。 –

0

我的主要問題是,我更改了名單,因爲我通過 它們移動,所以如果我檢查的第一個節點,我刪除它,我必須 檢查的第一個節點再次因爲現在它的一個新的,所以我保持 檢查,直到頭好,這是正確的做法?

原則上這是正確的方法,但您必須這樣做,不僅是爲了頭,而且是爲每個列表中的每個節點。您的代碼不適用於所有情況,例如, G。

 //while the first is still > than the max age of this category 
     while(childP->age > MaxAges[i]){ 
       if(i != (N-1)){ 
        childP->next = Age_categories[i+1]; 
        Age_categories[i+1] = childP; 
       }else{ 
        Age_categories[i] = childP->next; 
       } 
       childP = childP->next; 
     } 

構成一個無限循環,如果讓我們說0歲組的頭部孩子已經成爲4歲。


考慮這個正確的代碼,這是短,因此給出了錯誤的機會較小:

// Remove or Move Loop 
    for (i = 0; i < N; i++) 
    { 
     struct child **chPA; // address of pointer to node under check 
     // for each node in age group i 
     for (chPA = &Age_categories[i]; childP = *chPA;) 
      if (childP->age > MaxAges[i]) 
      { 
       *chPA = childP->next; // remove node from this list 
       if (i != N-1) 
       { 
        struct child **chPA; // address of pointer to node in next group 
        // find where in next group to insert the aged node 
        for (chPA = &Age_categories[i+1]; childptr = *chPA; 
         chPA = &childptr->next) 
         if (childptr->cid > childP->cid) break; 
        (*chPA = childP)->next = childptr; 
       } 
       else 
        free(childP); // delete the grown out node 
      } 
      else 
       chPA = &childP->next; // proceed to next node 
    } 

(它根據其cid因爲你的代碼註釋中插入一個節點中的下一個更高年齡組

struct child *next; /* Singly-linked, sorted by id */