2013-08-27 47 views
6

Làm cách nào để xóa nút khỏi danh sách được liên kết?C Xóa nút khỏi danh sách được liên kết

Đây là mã của tôi:

void RemoveNode(Node * node, Node ** head) { 
    if (strcmp(node->state, (*(*head)->next).state) == 0) { 
     Node * temp = *head; 
     *head = (*head)->next; 
     free(temp); 
     return; 
    } 

    Node * current = (*head)->next; 
    Node * previous = *head; 
    while (current != NULL && previous != NULL) { 
     if (strcmp(node->state, (*current->next).state) == 0) { 
      Node * temp = current; 
      previous->next = current->next; 
      free(temp); 
      return; 
     } 
     current = current->next; 
     previous = previous->next; 
    } 
    return; 
} 

Nhưng tôi cứ bị lỗi seg.

Tôi cảm thấy như tôi đang làm điều gì đó ngu ngốc .... Bất kỳ ý tưởng nào?

+1

Tại sao 'trước = trước-> tiếp theo' thay vì chỉ« previous = current' trước khi chuyển nhượng lại hiện tại? –

+0

Ngoài ra, nếu bạn nhận được lỗi phân đoạn, hãy chạy chương trình của bạn trong trình gỡ lỗi. Nó sẽ dừng lại nơi bạn có vấn đề của bạn, và cho phép bạn kiểm tra các callstack và các biến. Ít nhất bạn nên chỉnh sửa câu hỏi của bạn để bao gồm các callstack, và chỉ ra nơi trong mã được cung cấp vụ tai nạn xảy ra. –

+0

Ngoài ra, bạn * luôn luôn * có một con trỏ '(* head) -> next' hợp lệ không? Điều gì xảy ra nếu danh sách trống? Điều gì sẽ xảy ra nếu chỉ có một nút trong danh sách? –

Trả lời

5

tôi đoán:

void RemoveNode(Node * node, Node ** head) { 
    if (strcmp(node->state, ((*head)->state) == 0) { 
     Node * temp = *head; 
     *head = (*head)->next; 
     free(temp); 
     return; 
    } 

    Node * current = (*head)->next; 
    Node * previous = *head; 
    while (current != NULL && previous != NULL) { 
     if (strcmp(node->state, current->state) == 0) { 
      Node * temp = current; 
      previous->next = current->next; 
      free(temp); 
      return; 
     } 
     previous = current; 
     current = current->next; 
    } 
    return; 
} 
+4

Sẽ hữu ích hơn nếu bạn chỉ ra những gì bạn đã thay đổi. –

+0

Tôi đã thay đổi so sánh với giá trị 'tiếp theo' chỉ với giá trị hiện tại và tôi đã thay đổi bản cập nhật trước đó trong vòng lặp while. – Jiminion

+0

Cảm ơn, điều này chính xác! – Travv92

2

tôi sẽ khuyên bạn nên cố gắng làm điều này với đệ quy, để tránh sự cần thiết của một "con trỏ kép". Nó sẽ cực kỳ đơn giản hóa logic. This link có một lời giải thích rất tốt và thực hiện việc này đệ quy. Điều này đặc biệt thậm chí sẽ làm việc nếu bạn cố gắng để loại bỏ một nút từ một danh sách liên kết sản phẩm nào.

Node *ListDelete(Node *currP, State value) 
{ 
    /* See if we are at end of list. */ 
    if (currP == NULL) 
    return NULL; 

    /* 
    * Check to see if current node is one 
    * to be deleted. 
    */ 
    if (currP->state == value) { 
    Node *tempNextP; 

    /* Save the next pointer in the node. */ 
    tempNextP = currP->next; 

    /* Deallocate the node. */ 
    free(currP); 

    /* 
    * Return the NEW pointer to where we 
    * were called from. I.e., the pointer 
    * the previous call will use to "skip 
    * over" the removed node. 
    */ 
    return tempNextP; 
    } 

    /* 
    * -------------- RECURSION------------------- 
    * Check the rest of the list, fixing the next 
    * pointer in case the next node is the one 
    * removed. 
    */ 
    currP->next = ListDelete(currP->next, value); 


    /* 
    * Return the pointer to where we were called 
    * from. Since we did not remove this node it 
    * will be the same. 
    */ 
    return currP; 
} 
Các vấn đề liên quan