簡體   English   中英

在C中刪除雙向鏈表中的頭節點時出現問題

[英]Problem deleting head node in a doubly linked list in C

我正在嘗試在C中實現雙向鏈表。在編寫代碼時,我在嘗試刪除列表的第一個元素時遇到了問題。

這是一個說明問題的玩具示例:

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

 typedef struct Node{
     struct Node * next;
     struct Node * previous;
     int data;
 }Node;


 Node* create_dll(int array[], int arrSize){
     Node *current = (Node*)malloc(sizeof(Node));
     current->next = NULL;
     current->data = array[0];
     for(int i = 1; i < arrSize; i++){
         Node *temp = (Node*)malloc(sizeof(Node));
         temp->data = array[i];
         temp->next = current;
         current->previous  = temp;
         current = temp;
     }
     current->previous = NULL; 
     return current;
 }
 void print_dll(Node *head){
     if(head != NULL){
         Node *current = head;
         while(current!=NULL){
         printf("%d \t", current ->data);
             current = current->next;
         }
     }
     puts(" ");
 }

 void delete_head(Node *head){
     Node *current = head;
     head = head->next;
     //head ->previous = NULL;
     free(current);
 }
 void kill(Node *head){
     Node *current = head;
     while (current != NULL){
         Node *previous = current;
         current = current ->next;
         free(previous);
     }
 }

 int main(){
     int array [] = {1, 2, 3, 4, 5};
     int arrSize = 5;

     Node *head;

     head = create_dll(array, 5);

     print_dll(head);

     delete_head(head);
     print_dll(head);

     kill(head);
     return 0;

}

每當我嘗試在main中運行代碼(創建DLL),然后打印其中的內容,然后嘗試刪除第一個節點,然后再次打印列表,我得到以下結果:

    5   4   3   2   1    
    5    

現在,我知道一個修復方法是將head變為全局變量,但這在代碼的其他部分會有問題,而且我真的不想走那條路。 我也不想修改任何函數頭或main中的任何東西。

我確實通過實現具有head總是指向的虛擬節點的DLL來實現這一點,但我確信這個實現有一個簡單的修復方法可以避免所有這些。

基本上,如果我可以在delete_head函數中更改head指向並將此更改反映在main函數中,那將是一個解決方案。 否則,我很高興只是理解為什么這段代碼無法按我的意願行事。

很感謝任何形式的幫助! 謝謝!

問題是當你調用delete_head時,C參數傳遞是按值,因此返回時不會更改head。 你需要像這樣實現它:

void delete_head(Node **head){
            Node *current = *head;
            *head = current->next;
            //head ->previous = NULL;
            free(current);
}

並稱之為: delete_head(&head);

訣竅是,所有外部指針都指向各個節點 因此,當您從列表的其余部分中刪除頭部時,所有指向head的指針都會指向它 - 您自己獲得單個節點,而不是列表的其余部分。

我會通過添加一個額外的結構來解決這個問題

typedef struct DLL{
    struct Node * head;
} DLL;

如果要創建列表,請創建指向頭部的DLL ,而不是返回頭部本身。 現在,當您想要更改頭部時,請更改DLL結構中的指針。 所有對DLL本身的引用都可以保持不變,但現在它內部的head已經改變了,所有這些引用都會在它們查找時看到新的head

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM