2017-10-19 22 views
1

Salut les gars j'apprends C et je vais avoir du mal à comprendre ce code:liste chaînée et Pointeurs en C

struct node { 
int data; 
int key; 
struct node *next; 
}; 

struct node *head = NULL; 
struct node *current = NULL; 

//delete a link with given key 
struct node* delete(int key) { 

//start from the first link 
struct node* current = head; 
struct node* previous = NULL; 

//if list is empty 
if(head == NULL) { 
    return NULL; 
} 

//navigate through list 
while(current->key != key) { 

    //if it is last node 
    if(current->next == NULL) { 
    return NULL; 
    } else { 
    //store reference to current link 
    previous = current; 
    //move to next link 
    current = current->next; 
    } 
} 
//found a match, update the link 
if(current == head) { 
    //change first to point to next link 
    head = head->next; 
} else { 
    //bypass the current link 
    previous->next = current->next; 
}  

return current; 
} 

Le code fonctionne réellement, il supprime les éléments de la liste chaînée en C mais Je ne comprends pas comment, si nous ne sommes pas toucher la variable struct tête (Voici ma peine):

//bypass the current link 
    previous->next = current->next; 

Je comprends le code mais je ne comprends pas comment la tête variable va changer si nous ne fais pas la tête = quelque chose.

De plus, la façon dont il est posible d'avoir deux variables avec le même nom (courant)

Merci

Btw J'ai trouvé le code ici: https://www.tutorialspoint.com/data_structures_algorithms/linked_list_program_in_c.htm

+1

Parce que vous avez omis les définitions de fonctions dans le tutoriel et le code affiché en ligne inepte. –

+0

Vous manquez vraiment une partie de la fonction. Voir le tutoriel plus en détail. La partie que vous avez ici ne trouve que celle à supprimer. Le code ci-dessous fait la suppression. – Kajienk

Répondre

1

La façon dont le code est publié ne fonctionne pas, car il manque effectivement la suppression du nœud initial dans le pointeur head. Cependant, vous avez omis du code qui résout apparemment le problème. Voici le code de l'delete d'origine:

//found a match, update the link 
if(current == head) { 
    //change first to point to next link 
    head = head->next; 
} else { 
    //bypass the current link 
    previous->next = current->next; 
} 

C'est là le code ajuste le pointeur de tête après la suppression. Le seul problème avec ce code est qu'il n'appelle jamais free n'importe où dans le corps du tutoriel, mais malheureusement, des erreurs comme celle-là sont communes à la fois sur les sites web gratuits et dans les livres.

Voici une implémentation qui fait la même chose avec un double pointeur:

struct node* delete(int key) { 
    struct node** ptrCurrent = &head; 
    while (*ptrCurrent) { 
     if ((*ptrCurrent)->key == key) { 
      struct node* tmp = *ptrCurrent; 
      *ptrCurrent = (*ptrCurrent)->next; 
      free(tmp); 
      break; 
     } 
     ptrCurrent = &((*ptrCurrent)->next); 
    } 
} 
+0

On dirait que le meilleur anwser. Excusez-moi monsieur, quels sont les deux ** après le noeud? – Edw4rd

+0

@ Edw4rd C'est un pointeur vers une déclaration de pointeur.Parcourez le code pour voir comment cela fonctionne: il pointe d'abord vers «head», puis il se déplace vers le «next» du premier nœud, puis vers le «next» du second nœud, et ainsi de suite. Cela vous permet d'assigner un pointeur à 'head' ou' next' sans savoir lequel vous assignez. – dasblinkenlight

0

Pour une struct a-> b les accès que est stocké dans b dans struct a. Cela signifie que la ligne current = current-> next est en effet en train de dire que le courant réglé est égal à ce qui est stocké dans la variable suivante dans le courant struct. En d'autres termes, passez à l'élément suivant de la liste.

+0

Je suis désolé j'ai foiré et raté quelques parties de la fonction, Pouvez-vous relire ma question s'il vous plaît? – Edw4rd

+0

Ceci ne change pas l'explication de current-> next. En ce qui concerne la deuxième partie je ne crois pas que vous avez deux variables différentes. noeud de la structure * current = NULL; c'est dire prendre la structure du type de note nommé current et le rendre nul, ne pas le re-déclarer. – Falderol

0

Pour la ligne

previous->next = current->next; 

La variable previous a l'adresse de l'élément précédent dans la liste liée. Il peut avoir l'adresse de head comme n'importe quel autre article.

Vous venez de définir l'élément suivant est celui derrière. Similaire à:

Vous n'avez pas besoin de changer head si vous supprimez un élément de la liste (sauf le premier - le head et le second).