2012-07-19 60 views
4

我想編寫一個函數,它獲取指向鏈表的頭的指針,並從列表中刪除每個第二個元素的列表。這份名單是類型元素的連接的元件:c中的指針刪除鏈表中每第二個元素的函數

typedef struct element{ 
    int num; 
    struct element* next; 
}element; 

我是新來的所有這些指針運算,所以我不知道我寫正確的:

void deletdscnds(element* head) { 
    element* curr; 
    head=head->next; //Skipping the dummy head// 

    while (head!=NULL) { 
     if (head->next==NULL) 
      return; 

      else { 
       curr=head; 
       head=head->next->next; //worst case I'll reach NULL and not a next of a null// 
       curr->next=head; 
      } 
     } 
    } 

我不停地變化着它因爲我一直在發現錯誤。你能指出任何可能的錯誤嗎?

+5

哎呀!在你這樣做了一段時間後,你會在泄露的記憶中站立得很深。你還沒有刪除任何東西......你剛剛失去了它。 – dmckee 2012-07-19 17:29:18

+0

我應該在放手之前使用「免費」功能嗎? – Jozef 2012-07-19 17:30:55

+0

在刪除curr之前,您必須獲取curr-> next的值。 – 2012-07-19 17:31:31

回答

9

如果按照節點對來考慮鏈表,算法會簡單得多。循環的每次迭代都應該處理兩個節點 - headhead->next,退出後離開head等於head->next->next。不要忘記刪除中間節點也很重要,如果您將其從列表中刪除,否則您將看到內存泄漏。

while (head && head->next) { 
    // Store a pointer to the item we're about to cut out 
    element *tmp = head->next; 
    // Skip the item we're cutting out 
    head->next = head->next->next; 
    // Prepare the head for the next iteration 
    head = head->next; 
    // Free the item that's no longer in the list 
    free(tmp); 
} 
1

這可能是最簡單的遞歸方面顯現這個問題,像這樣:

// outside code calls this function; the other functions are considered private 
void deletdscnds(element* head) { 
    delete_odd(head); 
} 

// for odd-numbered nodes; this won't delete the current node 
void delete_odd(element* node) { 
    if (node == NULL) 
    return; // stop at the end of the list 
    // point this node to the node two after, if such a node exists 
    node->next = delete_even(node->next); 
} 

// for even-numbered nodes; this WILL delete the current node 
void delete_even(element* node) { 
    if (node == NULL) 
    return NULL; // stop at the end of the list 
    // get the next node before you free the current one, so you avoid 
    // accessing memory that has already been freed 
    element* next = node->next; 
    // free the current node, that it's not needed anymore 
    free(node); 
    // repeat the process beginning with the next node 
    delete_odd(next); 
    // since the current node is now deleted, the previous node needs 
    // to know what the next node is so it can link up with it 
    return next; 
} 

對我來說,至少,這有助於澄清需要在每一步做什麼。

我不會建議實際使用這種方法,因爲在C語言中,遞歸算法可能會佔用大量內存,並導致堆棧溢出,而這些編譯器並未優化它們。相反,dasblinkenlight的答案有你應該實際使用的代碼。

相關問題